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

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

share|improve this question
1  
No, this is the whole code. Newlines are 0a. – knezi yesterday
2  
@Rahul the hexadecimal code of the Unix linefeed character – PSkocik yesterday
2  
Is the $BASH_ENV set? – roaima yesterday
2  
@PSkocik that is really weird. bash -c "source /tmp/test" works. – knezi yesterday
5  
Ah-ha! Please add that it works with bash -c to your question. Then, show us the contents of your ~/.bashrc file, there's probably something there that's screwing things up. – terdon yesterday
up vote 61 down vote accepted

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.

share|improve this answer
13  
You are completely right. I have set: alias fi='find -type f | xargs grep -H '. – knezi yesterday
3  
Get rid of that alias now! :) – Mark Stewart 20 hours ago
5  
I am astounded that anybody managed to figure out such an obscure problem. Well done, sir. – MathematicalOrchid 12 hours ago
2  
@MathematicalOrchid I suspected that something was aliased (because of the interactive shell), set was ruled out by the output, and alias if='foo "' (a trailing open quote gave an error about the missing quote, and so the last option was aliasing fi. – muru 10 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.