bashを、shというシンボリックリンクから呼んだ場合の動作の違い

  • このエントリーをはてなブックマークに追加
  • Pocket

/bin/sh -> /bin/bash
このようにshのシンボリックリンクがbashであるときに、

$ sh -c 'echo $SHELL'

と実行すると

/bin/bash

と返ってきますが、bash 2.0のプロセス置換の機能をsh -cでつかってみると、

$ sh -c 'echo $SHELL; echo $0; paste <(cat tmp;) <(cat tmp;)'
sh: -c: line 0: 期待してない token `(' のあたりにシンタックスエラー

となり、reduced bashというか、低機能bashというか、無印shの振る舞いをしてくれます。
一方、bashとして呼ぶと、bashとして機能します。

$ bash -c 'echo $SHELL; echo $0; paste <(cat tmp;) <(cat tmp;)'
/bin/bash
bash
1.0000 1.0000 0.0000 1.2000 5 ...

さらに、

$ ln -s /bin/bash mysh

として、./mysh -> /bin/bashとしてから、次のようにすると、bashとして機能します。

$ ./mysh -c 'echo $SHELL; echo $0; paste <(cat tmp;) <(cat tmp;)'
/bin/bash
./mysh
 1.0000 1.0000 0.0000 1.2000 5 ...

呼び出しもとを判別して、無印shとして振る舞うようになっているようです。
shコマンドが呼ばれる場面でbashのコマンドを使いたい場合には、阻止されてしまいます。

解決法

zsh をリンクしてみた!
SHELLはなぜか /bin/bashだ。

$ zsh -e 'echo $SHELL'
/bin/bash

しかし、zshだと期待通りに動きました。これでなんとかなりそうです。

$ sh -c 'echo $SHELL; echo $0; paste <(cat tmp;) <(cat tmp;)'
/bin/bash
sh
1.0000 1.0000 0.0000 1.2000 5 ...
  • このエントリーをはてなブックマークに追加
  • Pocket

コメントを残す