Why aliases in a non-interactive Bash shell do not work

21,092

Solution 1

The command shopt -s expand_aliases will allow alias expansion in non-interactive shells.

Solution 2

.bashrc is only processed by interactive shells.

In addition, aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt. Unless, of course, POSIX mode is invoked by calling the shell with the name sh instead of bash.

People who use aliases a lot often source their .bashrc at the end of their profile so that the aliases are there even for non-interactive shells. This might not be the best way, but it is pretty common.

It's things like this that lead me to believe that in the 21st century we should abandon shell scripts in favor of a full-blown language like Python. It's a lot more predictable.

Solution 3

You have to

shopt -s expand_aliases

in the file pointed to in your BASH_ENV

Solution 4

I had similar issue, in the end, I found out that ~/.bashrc was all I needed.

However, in Ubuntu, I had to comment the line that stops processing ~/.bashrc :

If not running interactively, don't do anything
[ -z "$PS1" ] && return
Share:
21,092
nisah
Author by

nisah

Updated on July 09, 2022

Comments

  • nisah
    nisah almost 2 years

    I am trying to use aliases in a non-interactive bash shell. I have defined my aliases in ~/.bashrc and I have set the variable BASH_ENV=~/startUpFile. The contents of the startUpFile are source ~/.bashrc.

    I can see that my aliases are recognized, when I execute the alias command. However, if I try to use an alias defined in ~/.bashrc, Bash can't recognized it. It gives me the unknown command error.

    With the TCSH shell it is pretty easy to do this because the ~/.cshrc file is always read.

    Any ideas how I can do this with a Bash shell?

  • Russell Smith
    Russell Smith over 14 years
    python makes for an abysmal interactive language. You can't cut/paste random bits of code unless the whitespace is exactly what you need. tclsh makes for a darn decent shell though -- it has built-in the ability to exec shell commands if the command you type isn't a known tcl command. Plus, it's very nature makes interactive use feasible. However, as much as a fan of Tcl that I am, I still prefer good ol' bash for interactive use. It's a pity tksh never quite reached escape velocity.
  • Vinko Vrsalovic
    Vinko Vrsalovic over 14 years
    The /etc/profile trick will only work for non-interactive shells being supplied the --login option
  • Michael Dillon
    Michael Dillon over 14 years
    You are right, Python makes an abysmal interactive language. You should use bash. But if you have to write a script, do it in Python. Since it is an object-oriented language, you reuse bits of code by writing them as classes, methods and functions. Scripting is the same as programming so use a powerful programming language like Python. But for interaction, for two or three command pipelines, bash is fine.
  • Admin
    Admin over 14 years
    Opinion alert! Opinion alert! (Not that there is inherently anything wrong with Python -- save it being dynamically typed O.o -- but Ruby and Perl (and who knows what else) are also good contenders in that market)
  • Alex Gray
    Alex Gray over 12 years
    you can most definitely write "reusable" functions in bash... # ThatsHot (){ echo "Thanks, gorgeous."; }; ThatsHot
  • Aquarius Power
    Aquarius Power about 10 years
    it was not working on alias used on functions until I moved my alias definition to BEFORE my function definitions; the alias seem to be expanded when the function definition is read!
  • tripleee
    tripleee almost 8 years
    Perhaps also mention that even with this, aliases will not yet be available in the physical line of code which contains this statement, so a one-liner with this will not work. A workaround is to use a newline instead of a semicolon between commands ssh remote $'shopt -s expand_aliases\nll'
  • tripleee
    tripleee almost 8 years
    An alternative (from duplicates - see "Linked questions" to the right) is to run bash -i to force the shell to be interactive.
  • Quantum7
    Quantum7 over 4 years
    I prefer checking $- for interactivity: [ $- == *i* ]] && myalias will only call myalias in interactive shells