0
$ alias bb=hello

$ cat test.sh 
#! /bin/bash

alias bb
echo "$bb"

$ ./test.sh 
./test.sh: line 3: alias: bb: not found

Is it because alias is not inherited by a child bash process for the script from the parent bash process?

$ source ./test.sh 
alias bb='hello'

The content in the script is executed in the bash process, so the alias exists. But the alias is not expanded.

Bash manual says

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt

But the content in the script being sourced is executed in the interactive bash process, so why is the alias not expanded?

Thanks.

Tim
  • 101,790

2 Answers2

4

If you run the script as

./test.sh

then it’s run in its own, non-interactive shell, not in the current interactive shell. You’d need

. ./test.sh

which is equivalent to the

source ./test.sh

in your second example.

See What is the difference between sourcing ('.' or 'source') and executing a file in bash?

As for echo "$bb", parameter expansion doesn’t expand aliases:

Aliases allow a string to be substituted for a word when it is used as the first word of a simple command.

Stephen Kitt
  • 434,908
  • Thanks. I mentioend source ./test/sh – Tim Oct 31 '18 at 13:11
  • @Tim And it worked when you did that, didn't it? You got the result of alias bb outputted. The echo "$bb" would have outputted an empty line unless you had a variable called bb with a value. – Kusalananda Oct 31 '18 at 13:12
-3

Shell scripts are run in a sub-shell (not in the current process that prints your prompt).

In order to make the execution of shell scripts predictable, aliases are cleared in the sub-shell before running that script. If that did not happen, scripts would interpret unknown aliases and could do anything, depending on what aliases are just active.

Warning: If you source a script, this affects the main shell, but at least genetic shells (shells that depend on the historic Bourne Shell source, e.g. ksh or bosh) parse script files as a whole (as if all newlines had been replaced by semicolons) before running the code from the sourced script. This causes alias definitions from inside a sourced script not to become active in that sourced script itself.

schily
  • 19,173
  • 1
    Note that sub-shell is not the problem here. alias bb=foo; (alias bb) outputs alias bb='foo' even though that alias command is run in a sub-shell. The alias is lost in ./test.sh because a new shell interpreter is started to interpret that script. It would still be lost if you ran exec ./test.sh where test.sh is run in the same process (but still starts a new interpreter). – Stéphane Chazelas Oct 31 '18 at 13:39
  • This is why I explained that the sub-shell clears the aliases before running the script. – schily Oct 31 '18 at 13:51