📝

curl -sf (address.sh) | sh -sで(address.sh)に書いたecho $0の結果が知りたかった

2023/08/29に公開

https://qiita.com/items/a70e50d1a31754399657


お詫び

Qiitaの元記事にて、区切り線を「---」で書いている場所があり、これがZennの記法に干渉して一部うまく表示できない記事がある事を認識しています。
全ての記事を精査しきれていないため、お手数ですがお見かけの際は教えていただけると大変喜びます。


結論

パイプで実行したshが返されます。
たとえば、タイトルのように(略) | sh -sだと、sh
これをbashとかzshに変えたらそれぞれの結果になりました。

検証用URL(curlで呼び出せます)

# curlで実行された場合に何を出力するか検証
echo $0

検証用URL(r_and_d.sh)

※普段からブランチや場合によりリポジトリをいじっているので、動かなくなったら↑の内容をご自身の環境において試してみてください。

curl -sf https://raw.githubusercontent.com/shimajima-eiji/Settings_Environment/%2314_20211225_ver1_brew_upgrade_sh/for_Mac/r_and_d.sh | sh -s

補足

当然ですが、ファイルをローカルに保存して、ローカルから呼び出すと$0は「ファイル名」になります。
shだろうがbashだろうがzshだろうがファイル名です。

補足の補足

試しに、which shの結果である/bin/shで実行したところ、結果は/bin/shになりました。

curl -sf https://raw.githubusercontent.com/shimajima-eiji/Settings_Environment/%2314_20211225_ver1_brew_upgrade_sh/for_Mac/r_and_d.sh | /bin/sh -s

これもbashのフルパス、zshのフルパスに変えてもそれぞれ同様の結果です。

疑問、そして理解したこと

これは質問に投稿するべきだと思ったのですが、記事を分けると上記を説明する必要があるので気付いた有識者の方に見てもらえればと思います。

$0とはそもそもなんなのか?

私は「スクリプトを実行しているもの(名前)が格納されている」という認識をしていました。
なので、

  • shで実行すればshが、
  • /bin/shで実行すれば/bin/shが
  • ファイル名から呼び出せばファイル名が

それぞれに入っているという認識です。

今回の場合、curlでファイルを文字列として受け取って、それをパイプ先に渡しているだけなので、実体はパイプで指定したものなんだろうという認識をしました。
これは、例えばログインシェル(対話モード)でecho $0を実行した時の結果がそのまま出ている($SHELLと同じはず)ので、同じことがcurl... | shにも起こっただけなんだろうという理解です。

GitHubで編集を提案

Discussion