Pythonスクリプトの1行目の意味

Pythonスクリプトの1行目、

#!/usr/bin/env python3

これが、今までおまじないになっていたので、調べてみました。

シバン

この1行目はシバン(shebang)といい、UNIXスクリプトを実行する際の、インタプリタを指定します。
インタプリタとは、スクリプトを解釈するためのプログラムです。

#![インタプリタのパス] [インタプリタの引数]

という書式で指定します。
指定することで、インタプリタに、インタプリタの引数と実行したスクリプトファイルのパスが渡ります。

なお、この指定は、スクリプトファイルに実行権限を付与し、直接実行した時しか有効になりません。
python spam.py ではインタプリタを指定し、実行されています)

Pythonのシバンの場合、インタプリタのパスが /usr/bin/env となっています。
Pythonインタプリタのパスを直接指定しているわけではありません。

/usr/bin/env とは一体何者なのでしょうか。

/usr/bin/env

/usr/bin/env とは、envコマンドを実行した時に実行されるファイルです。
このファイルパスをインタプリタのパスとして指定することで、envコマンドが実行されています。

envコマンドの書式は以下の通りです。

env [オプション] [環境変数=値 ....] [コマンド]

env [コマンド] は、現在の環境変数でコマンドを実行します。
env python3 で、環境変数PATHのディレクトリ下に存在するpython3ファイルを実行します。

envコマンドを経由することで、インタプリタのパスが変更された場合でもPATHさえ通っていれば、そのインタプリタを使うことができます。

例えば、python3が/usr/bin下に存在し、カレントディレクトリにあるspam.pyを直接実行した場合、以下のコマンドが実行されたのと同等になります。

$ /usr/bin/python3 ./spam.py

そもそもシバンってどこで解釈されてるの?

execve() というシステムコールで解釈されているようです。

「ようです」というのは、まだきちんと理解できていないから…。
すみません。
Linux OSの仕組みもいずれ勉強したいです。

おまけ

シバンにインタプリタの引数を指定することで色々遊べます。
※ただし、シバンが複数引数を受け付けるかはOS依存のようです。
(参考URL:https://cpplover.blogspot.com/2013/08/shebang.html

デバッガ実行

#!/usr/bin/env python3 -m pdb

スクリプトを直接実行した場合、デバッガ実行になります。

インタプリタ以外のコマンド

#!/bin/echo "spam, ham, eggs"

実行結果:

$ ./spam.py
"spam, ham, eggs" ./spam.py

インタプリタとは全く関係のないコマンドを指定することもできます。
ただしスクリプトは解釈されません。
悪用もできますが、やめましょう。


以上、お粗末さまでした。