次のスクリプトがあります:
#!/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
実行すると動作しますが、非対話型シェル(シェルスクリプトを実行するタイプのシェル)ではエイリアスが利用できないため、ソースすると失敗します。bash マニュアル:
シェルが対話的でない場合は、
expand_aliases
シェルオプションがshopt
(ショップビルトイン)。
ただし、source
何かを実行すると、現在のシェルで実行されます。このシェルは対話型であるため、すでにエイリアスがロードされており、fi
エイリアスが認識されてソースが壊れます。