先日仕事でシェルスクリプトを書いていたのですが、想定しないsyntaxerrorが出て、かなり詰まったことがあったのでメモがてら残しておきます。
事象と解決策
詰まったスクリプトは次のようなものでした。
#!/bin/bash
diff <(echo aaa) <(echo bbb)
これを次のように実行するとエラーになります。
$ sh difftest.sh
difftest.sh: line 3: syntax error near unexpected token `('
difftest.sh: line 3: `diff <(echo aaa) <(echo bbb)'
これの解決策が分からず、数時間を無駄にしてしまいました。結論として、次のように実行すると想定していた通りの動作になりました。shではなくbashとして実行してあげます。
$ bash difftest.sh
1c1
< aaa
---
> bbb
原因
このdiffコマンドでは、<()と記載する、プロセス展開という記法?をつかっているのですが、この記法はshでは解釈されず、bashでなら解釈されます。よってshではエラーに、bashでは正常終了したというわけです。
でも、シェバンに#!/bin/bashと記載してるし、/bin/shは/bin/bashへのシンボリックリンクじゃないの?、と思うかもしれません(私もこう思っていました)。これはその通りなのですが、実はbashスクリプトをshで実行した時はbashはshをエミュレートするようになるようです。これをPOSIX互換モードと呼ぶそうです。
つまりは、動作するのはbashなんだけど、その振る舞いはshになるということです。
ややこしい。。。
なのでbashとしての動作を期待する場合は、必ずbashコマンドで実行しましょう。
コメント