Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

In my ~/.bashrc file reside two definitions:

  1. commandA, which is an alias to a longer path
  2. commandB, which is an alias to a Bash script

I want to process the same file with these two commands, so I wrote the following Bash script:


#!/bin/bash

for file in $@
    do
    commandA $file
    commandB $file
done

Even after logging out of my session and logging back in, Bash prompts me with command not found errors for both commands when I run this script.

What am I doing wrong?

share|improve this question
2  
BTW, there's no need to log in and out to have an alias recognized. You need just do source ~/.bashrc. –  Tshepang Nov 25 '10 at 19:10
add comment

6 Answers

up vote 30 down vote accepted

First of all, as ddeimeke said, aliases by default are not expanded in non-interactive shells.

Second, .bashrc is not read by non-interactive shells unless you set the BASH_ENV environment variable.

But most importantly: don't do that! Please? One day you will move that script somewhere where the necessary aliases are not set and it will break again.

Instead set and use environment variables as shortcuts in your script:

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
    do
    "$CMDA" "$file"
    "$CMDB" "$file"
done
share|improve this answer
add comment
[cmd line] > bash -i [your script's file path]

The i is for interactive and sources your bash profile for you.

share|improve this answer
add comment

Aliases can't be exported so they're not available in shell scripts in which they aren't defined. In other words, if you define them in ~/.bashrc they're not available to your_script.sh (unless you source ~/.bashrc in the script, which I wouldn't recommend but there are ways to do this properly).

However, functions can be exported and would be available to shell scripts that are run from an environment in which they are defined. This can be done by placing this in your bashrc:

foo()
{
    echo "Hello World!"
}
export -f foo

As the Bash manual says, "For almost every purpose, shell functions are preferred over aliases."

share|improve this answer
add comment

I found sometimes bash script doesn't recognize export either. However, changing it to

#!/bin/sh

works for me.

share|improve this answer
add comment

If you look into the bash manpage you find:

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS below).

So put a

shopt -s expand_aliases

in your script.

Make sure to source your aliases file after setting this in your script.

shopt -s expand_aliases
source ~/.bash_aliases
share|improve this answer
    
I placed it in my script, but it's still not working. Same error. –  Zaid Sep 2 '10 at 10:29
    
Adding shopt -s expand_aliases source ~/.bash_aliases works perfectly for me. Often there is a form of interactive shell detection in .bashrc like this: # If not running interactively, don't do anything [ -z "$PS1" ] && return @Zaid, Maybe you want to check for that in the file you sourced. –  Frank Schubert Apr 4 '13 at 1:46
    
excellent! saved my scripts!! :) it is so hard to read/search/browse info and manpages in the terminal that I just gave up long ago and go search on the internet... –  Aquarius Power Sep 17 '13 at 19:24
add comment

When you run your script, a new instance of bash is run. This instance is not interactive and therefore does not read your .bashrc file.

A simpler way to do what you want can be simply to force reading the the .bashrc file by using source. Add the following line at the beginning of your script:

#!/bin/bash

# Add the following line to your script. 
source ~/.bashrc

for file in $@
    do
    $CMDA $file
    $CMDB $file
done
share|improve this answer
2  
Actually this will fail because it's not just a matter of the file not being sourced, even if it was the aliases would not be expanded. Your answer ripped off part of @hop's answer because it has variables instead of aliases which is what you would have to do, but it wouldn't work for the users aliases. Then you add in the one part he begged the user not to try which was sourcing a private bashrc file from a script. If you were going to do that you would want to setup a library file and keep it with the script and then source THAT from the bashrc for the users use. –  Caleb Aug 20 '11 at 20:17
add comment

protected by slm 8 hours ago

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.