daisuzz.log

netdataのinstallスクリプトが実行できない話

ISUCONの練習でnetdataのinstallシェルスクリプトを書いていたらshとbashの違いでハマったので、忘備録として残していきます。

問題

#!/bin/bash

...

bash <(curl -Ss https://my-netdata.io/kickstart.sh) --no-updates --dont-wait --stable-channel --disable-telemetry

上記のシェルスクリプトsh setup.shで実行したところ、以下のように途中でエラーが吐かれてしまいました。

$ sh setup.sh

...

setup.sh: line 27: syntax error near unexpected token `('
setup.sh: line 27: `bash <(curl -Ss https://my-netdata.io/kickstart.sh) --no-updates --dont-wait --stable-channel --disable-telemetry'

原因

netdataのinstallに利用していた<(は、process substitiionというbashの機能だったため、shコマンドでシェルスクリプトを実行するとこの機能が使えないことが原因でした。 RedHat系のLinuxでshコマンドをlsでみてみると、bashシンボリックリンクになっています。

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jul 21  2020 /bin/sh -> bash

一見するとshとbashコマンドで同じ挙動を取るように見えますが、実際はshコマンドをデフォルトの設定のまま使うとPOSIXモードが有効になっているため、bashの機能が使えません。 bashの設定を見てみると以下のようにposixがoffになっています。

$ bash 
$ set -o

...
posix           off
...

一方でshの設定を見てみるとposixがonになっています。

$ sh
$ set -o

... 
posix           on
...

今回のケースでは、shコマンドでシェルスクリプトを実行したため、POSIXモードがonになり、process substitionが使えずエラーになっていました。

sh setup.shではなくbash setup.shとすることで無事エラーにならずセットアップ スクリプトを実行することができました。

参考

shell - Difference between sh and bash - Stack Overflow

/bin/shと/bin/bashの違い(とcronでのシェル)

Bash POSIX Mode (Bash Reference Manual)

bashがsh互換(posix)モードで動く時 – Siguniang's Blog