2017-9-23

シェルスクリプトによくある1行目の「#!」の意味

技術

要約

Shebang(シェバング)という。

CUI からファイル名を直接叩いた際、基本的にはそのファイルにはマシン語が記述されている前提で解釈される。ただし Unix はファイルが「#!」から始まっている際は、その後に記述されているコマンド経由でファイルが実行される。

(追記)Mac の動作を見たところ、Shebang なしシェルスクリプトを直接ファイル名叩いても動作したので、マシン語前提というわけではないみたい。

npm install -gしたパッケージは当然 JavaScript で記述されてるんだけど、例えばcsscombがなんで CUI 上でnode csscombじゃなくcsscombだけで動くかというと Shebang が記述されているから。

詳細

よくあるのはこんなの

#!/bin/sh

echo 'hoge';

よく「シェルスクリプトを書く際のおまじない」的な感じで説明されてる。実際には前述の通り、ファイル名を叩いた際に「/bin/sh」経由でファイルが実行される。

これはシェルスクリプトにかぎらず、node.js 等インタプリタ上で動かす前提のファイルにも適用出来て、例えば

#!/usr/local/bin/node

console.log('hoge');

という内容の「hoge」ファイルを作った場合

./hoge

だけで node.js 上でファイルが実行される。(もちろん Shebang なしでは動作しない)

なお、/usr/local/bin/nodeと書いたが、実際にはユーザーがどこに node を入れているのかわからないので

#!/usr/bin/env node

console.log('hoge');

という風に書いて各ユーザーの環境変数を読み込んで実行する。 /usr/bin/env に配置されている env コマンドは設定されている環境変数を出力するコマンド。SOME_ENV=HOGE node とやると環境変数 SOME_ENVHOGE が設定された上で node が実行されるので、 /usr/bin/env node とすることでパスを通している。なぜ #!node だと駄目なのかはわからない。

参考

#!/bin/sh は ただのコメントじゃないよ! Shebang だよ! - Qiita

いまさら聞けない、#! で始まる1行目の名前と env 指定時の挙動 - プログラマ 福重 伸太朗 ~基本へ帰ろう~