我有以下腳本:
#!/bin/bash
set -x
if :; then
echo a
fi
如果我運行bash /tmp/file
,a
會得到回顯,但如果我運行source /tmp/file
, 我得到:
bash: /tmp/test: line 6: syntax error: unexpected end of file
輸出:
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
命令的輸出shopt -p
和set -o
:http://pastebin.com/bsqc8aru
輸出set
:http://pastebin.com/S9KpqZAL
declare -fp
什麼也不產生。
我認為這source
與 相同bash
,但不是開始新會話,而是在當前會話中運行程式碼。誰能向我解釋這個錯誤?
我運行 bash GNU bash,版本 4.2.53(1)-release (x86_64-redhat-linux-gnu)。
答案1
如果我使用別名,我可以重現您的行為fi
:
$ alias fi=:
+ alias fi=:
$ . ./test
+ . ./test
++ set -x
bash: ./test: line 6: syntax error: unexpected end of file
它在執行時有效,但在獲取它時失敗,因為別名在非互動式 shell(運行 shell 腳本的 shell 類型)中不可用。正如中所解釋的bash 手冊:
當 shell 非互動式時,別名不會擴展,除非
expand_aliases
使用 shell 選項設定shopt
(請參閱內建商店)。
但是,當您source
執行某些操作時,它會在當前的 shell 中運行,因為它是互動的,所以已經載入了別名,因此fi
別名會被識別並中斷來源。