LoginSignup
8
5

More than 3 years have passed since last update.

あんまり意識しない #!/bin/sh はシバンという

Last updated at Posted at 2019-05-14

シェルスクリプトを書く時、よく #!/bin/bash とか #!/bin/sh とか書くけど、これが何かっていうとそのファイルを実行するためのインタプリタのパスを指定している。シバンとかシェバンとか言うらしいけど、日常生活で用いたことは余裕で一度もない。 !をBangって言うから、シェル・バンとか、#! でハッシュバンとか言うらしい

例えば下記のコマンドは自分のプロセスを表示する。ログインシェルはzshを使っている。

$ ps -p $$
  PID TTY           TIME CMD
48577 ttys004    0:00.46 -zsh

これを下記のようにシェルスクリプトにして、chmod +x a.sh とかで実行権限を与える。シバンはbashのパスを指定している。

a.sh
#!/bin/bash

ps -p $$

これを実行すると

$ ./a.sh
  PID TTY           TIME CMD
49563 ttys004    0:00.00 /bin/bash ./a.sh

bashで実行されている。

このシバンを下記のように変更する。

#!/bin/sh

ps -p $$

で、実行する。

$ ./a.sh
  PID TTY           TIME CMD
49698 ttys004    0:00.00 /bin/sh ./a.sh

shで実行されている。じゃあ、シバンを #!/bin/zsh にするとどうなるかっていうと、

$ ./a.sh
  PID TTY           TIME CMD
49812 ttys004    0:00.01 /bin/zsh ./a.sh

大方の予想通りzshで実行される。ちなみに実行時パスが通っていても、シバンは絶対パスじゃないと動かないらしい。

a.sh
#!zsh

ps -p $$
$ ./a.sh
zsh: can't open input file: \nps -p $$\n\M-|:D^E^A

要するにシバンとはスクリプトを実行するために、どのパスのインタプリタを使用するかということを絶対パス指定している。込み入ったシェルスクリプトを書くことはあんまりないけど、ときどき、 #!/usr/bin/env ruby とか指定されていることがある。これは env コマンドはパスの通ってるコマンドを実行するので、各環境のパスが通ったインタプリタにスクリプトを渡す、ということを表している。

シバンにはオプションも使える。(ものがある)例えばbashのシェルスクリプトは、ケースによって、よく -eux を渡すようにしている。 e はシェルスクリプト内で実行されたコマンドの返り値が0以外だったらシェルスクリプトを停止させる、 u は未定義の変数参照を許さない、 x はデバッグ情報を出力する。

変数未定義

$ cat a.sh
#!/bin/bash -eux

echo $HOGE
$ ./a.sh
./a.sh: line 3: HOGE: unbound variable

エラー時シェルスクリプト停止

$ cat a.sh
#!/bin/bash -eux

command_arimasen
echo "todoke"
$ ./a.sh
+ nainai_command
./a.sh: line 3: command_arimasen: command not found

ちなみにどうやって実行されているかというと

 cat a.sh
#!/bin/bash -eux

ps -p $$

上記を実行すると単純にオプションが渡されているのが分かる。

$ ./a.sh
+ ps -p 50934
  PID TTY           TIME CMD
50934 ttys004    0:00.00 /bin/bash -eux ./a.sh
8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5