Bash – If “bash ” works, why is “source ” throwing an error

bashshell-script

I have the following script:

#!/bin/bash
set -x
if :; then
    echo a
fi

If I run bash /tmp/file, a is echoed, but if I run source /tmp/file, I get:

bash: /tmp/test: line 6: syntax error: unexpected end of file

The output:

knezi@holly tmp]$set -x; source /tmp/test; set +x
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$set -x; command source /tmp/test; set +x
+ set -x
+ command source /tmp/test
+ source /tmp/test
++ set -x
bash: /tmp/test: line 6: syntax error: unexpected end of file
+ set +x

knezi@holly tmp]$bash -c "source /tmp/test"
+ bash -c 'source /tmp/test'
++ :
++ echo a
a


knezi@holly tmp]$od -c /tmp/test
0000000   #   !   /   b   i   n   /   b   a   s   h  \n   s   e   t    
0000020   -   x  \n   i   f       :   ;       t   h   e   n  \n  \t   e
0000040   c   h   o       a  \n   f   i  \n
0000051

Output of commands shopt -p and set -o: http://pastebin.com/bsqc8aru

Output of set: http://pastebin.com/S9KpqZAL

declare -fp produces nothing.

I thought that source does the same as bash, but instead of starting new session rather runs the code in the current one. Can anyone explain this error to me?

I run bash GNU bash, version 4.2.53(1)-release (x86_64-redhat-linux-gnu).

Best Answer

I can reproduce your behaviour if I alias fi:

$ alias fi=:
+ alias fi=:
$ . ./test
+ . ./test
++ set -x
bash: ./test: line 6: syntax error: unexpected end of file

It works when you execute it but fails when you source it because aliases are not available in non-interactive shells (the type of shell that runs shell scripts). As explained in the bash manual:

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see The Shopt Builtin).

However, when you source something, it is run in your current shell which, because it is interactive, has already loaded the aliases and therefore the fi alias is recognized and breaks the sourcing.

Related Question