57

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?

codeforester
  • 39,467
  • 16
  • 112
  • 140
nisah
  • 2,478
  • 3
  • 22
  • 20
  • 1
    This **[answer](http://superuser.com/a/183980/166579)** has nice explanation about `interactive` and `non-interactive` shell configuration. Also there is a tip about including `.bashrc` when you are in `non-interactive` mode. – Dmytro Jan 28 '13 at 13:57

4 Answers4

56

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

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
  • 3
    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! – Aquarius Power Jun 08 '14 at 04:35
  • 6
    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 Aug 30 '16 at 09:51
  • 1
    An alternative (from duplicates - see "Linked questions" to the right) is to run `bash -i` to force the shell to be interactive. – tripleee Aug 30 '16 at 09:52
16

.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.

Michael Dillon
  • 31,973
  • 6
  • 70
  • 106
  • 7
    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. – Bryan Oakley Oct 23 '09 at 21:27
  • The /etc/profile trick will only work for non-interactive shells being supplied the --login option – Vinko Vrsalovic Oct 23 '09 at 21:40
  • 1
    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. – Michael Dillon Oct 23 '09 at 22:15
  • 2
    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) –  Oct 23 '09 at 22:26
  • 1
    you can most definitely write "reusable" functions in bash... `# ThatsHot (){ echo "Thanks, gorgeous."; }; ThatsHot` – Alex Gray Feb 19 '12 at 06:47
13

You have to

shopt -s expand_aliases

in the file pointed to in your BASH_ENV

Vinko Vrsalovic
  • 330,807
  • 53
  • 334
  • 373
3

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
tomaszbak
  • 8,247
  • 4
  • 44
  • 37
  • I prefer checking `$-` for interactivity: `[ $- == *i* ]] && myalias` will only call myalias in interactive shells – Quantum7 Oct 08 '19 at 15:06