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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:


for file in $@
    commandA $file
    commandB $file

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
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
For my case I was connected by SSH agent remotely, after adding alias as I closed the SSH agent and connected again it started working. – dav Sep 6 '15 at 5:05
up vote 54 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:



for file in "$@"
    "$CMDA" "$file"
    "$CMDB" "$file"
share|improve this answer

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
Curiously, shopt -s expand_aliases doesn't have to go before the alias definition but before the alias use. Adding to @FrankSchubert: Interactive shell detection may also be done using $- which contains the options for the shell, specifically i if the shell is interactive. – valid Mar 20 '15 at 14:12
this isn't a correct answer... Sourcing your aliases inside your script isn't the answer. Your ~/.bash_aliases might depend on other stuff previously loaded on an interactive shell... The closest thing I found is changing your hashbang to #!/bin/bash -li Still not perfect. Ideally you should use functions and not aliases. – Stefanos Kalantzis Feb 5 at 11:47

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:

    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

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:


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

for file in $@
    $CMDA $file
    $CMDB $file
share|improve this answer
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

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


works for me.

share|improve this answer
[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
Best comment so far ! Thanks – Maxime May 8 '15 at 21:17

protected by slm Apr 18 '14 at 15:08

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, 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.