俺のメモ帖

とあるインフラ系SEのメモ帖。趣味や技術的なもとか書けたらいいなぁ。

【Linux】Shebangに記載する場合のbashとshについて【Shell】


Shebangとは?

シェルスクリプトの1行目に記述してある、

というやつで、当該スクリプトを処理するインタプリタを指定するものである。


こいつについて、最近知ったことをメモっておこう。

/bin/sh」と「/bin/bash」の関係について

たいていのLinuxディストリビューションでは、「/bin/sh」は「/bin/bash」へのリンクになっていると思う。

なので、Shebangに「#!/bin/sh」と書こうが「#!/bin/bash」と書こうが同じじゃね?ってずっと思ってた。

しかし、最近これが同じじゃないってことをようやく知ったんだ・・・

 

基本的に、自分がゼロから作るシェルはbashを記述するんだけど、デバッグの時は「sh -x シェルスクリプト名」って実行してた。。。

何がまずいって、同じ「/bin/bash」は「/bin/sh」ってリンクで起動された場合は、実行結果に違いが出るってこと。

/bin/sh」で起動した場合、「set -o」を実行してスクリプト実行モードを見てみよう。「posix」が「on」だ。

「/bin/bash」で起動した場合、「posix」が「off」だ。

 

これで何が違うかって言うと、「sh」から起動した場合の「posix」が「on」の場合は、出来るだけposix準拠の動作をしようとする。

つまりは、「bash」固有の拡張機能などがエラーになる場合がある。

 

まあ明示的にShebangに、上記をきちんと書いて試験とかしてれば、「/bin/sh」が書いてあればbashの命令がエラーになるんで、posixモードOnに従ったシェルが出来上がるだろうから、大して問題にはならんのですが。

 

今振り返ると、たとえばパイプで繋いだ各戻り値が欲しくてWEBで調べて使えるって書いてあった、PIPESTATUSが取れなくて、なんだよ嘘情報書きやがって・・・・とか思っていたのは、実はShebangに「/bin/sh」って書いていたからだったんだろうなw

 


この違いがやばいパターン

でだ、今回やべぇっって思ったのは、Shebangに「#!/bin/bash」って書いて、試験しつつ、デバッグは「sh -x シェルスクリプト名」でやってたパターンだ。

これ、Shebangに記載されたとおり、bashだから「posix」が「off」かと思いきや、先頭の「sh -x 」の方が生きて、実は「posix」が「on」で起動されること。

正常系はデバッグモード使わずに「bash」機能全開で問題なく仕様満たせてたけど、デバッグで実行するとなぜか上手くいかないとかそういうことが起こるわけで、しかもスクリプトには問題はないって言う事象に陥るわけですよ。

今回はそれでハマって、ようやくこの差異について知るに至りました。

 

いや、人間って実際にハマらないとこういうの覚えないもんですよね。

シェル作って20年くらいだけど、ようやくこれ知りました。恥ずかしい。

 

以上、これも社内ナレッジで共有だな!

入門bash 第3版

入門bash 第3版