#を入れましょうか!(シバン)Pythonスクリプトで、それはどのような形式を取るべきですか?


830

Pythonスクリプトにシバンを入れるべきですか?どんな形で?

#!/usr/bin/env python 

または

#!/usr/local/bin/python

これらは同等に移植可能ですか?最も使用されるフォームはどれですか?

注:竜巻のプロジェクトはシェバングを使用しています。一方、 Djangoプロジェクトはそうではありません。


70
2つ目は移植性がなく、ほとんどでないにしても多くのコンピューターで失敗します。
ディートリッヒエップ2011

4
#!/usr/bin/python最初のオプションと比較してどうですか?これは非常に多くのサンプルコードで見られます。編集:多分これが答えです.. stackoverflow.com/a/2429517/1156245
geotheory


1
私はいつもそれを使うと言います、なぜですか?"Zen Of Python"-2行目-"Explicitは暗黙よりも優れています。" python.org/dev/peps/pep-0020
JayRizzo

2
率直に言って、どちらも "正しい"とは言えません。作成者としてのあなたは、スクリプトを実行したときにPythonの正しいバージョンがどこにあるのかわからないからです。正しいシバンを追加するのはインストーラーの仕事であるべきです。
chepner 2018年

回答:


1117

スクリプトのシバン行はpython、ターミナルで事前に入力しなくても、またはファイルマネージャーでスクリプトをダブルクリックしたときに(適切に構成されている場合)、スタンドアロン実行可能ファイルのように実行されるスクリプトの機能を決定します。必須ではありませんが、通常はそこに置かれるので、誰かがエディタで開かれたファイルを見ると、彼らは自分が何を見ているのかすぐにわかります。しかし、あなたが使用していると思われるshebang行IS重要。

Python 3スクリプトの正しい使用法は次のとおりです。

#!/usr/bin/env python3

デフォルトはバージョン3.latestです。Python 2.7.latestの代わりに使用python2python3ます。

以下は使用しないでください(Python 2.xと3.xの両方と互換性のあるコードを作成しているまれな場合を除きます)。

#!/usr/bin/env python

PEP 394規定されているこれらの推奨事項の理由は、異なるシステムpythonを参照することpython2python3、異なるシステムで参照することもできるためです。現在python2、ほとんどのディストリビューションで参照されていますが、いずれ変更される可能性があります。

また、使用しないでください:

#!/usr/local/bin/python

「これらの場合、pythonは/ usr / bin / pythonまたは/ bin / pythonにインストールされる可能性があり、上記の#!は失敗します。」

- 「#!/ usr / bin / env python」vs「#!/ usr / local / bin / python」


4
@EliasVanOotegemあなたはPythonが中に発見されることを確信することができない場合は/usr/binどのようにあなたは、特定することができ、その後envに記載されています/usr/bin。Pythonが標準以外の場所にインストールされている場合は、Pythonが標準以外の方法でセットアップされており、結果としてスクリプトが高速に失敗することを意味します。Pythonインタプリタのプロパティについての仮定を立てて最高のものを期待するのではなく、
砂丘2014

65
@Dunes:env、常にで見つけること/usr/bin/、およびそのジョブが使用して(Pythonのような)のビンを見つけることですPATH。pythonがどのようにインストールされていても、そのパスがこの変数に追加され、env検索されます(そうでない場合、pythonはインストールされません)。それがの仕事でありenv、それが存在する理由のすべてです。これは、環境に警告するものです(インストールパスを含む環境変数を設定し、パスを含めます)。このコマンドは常に同じ場所にある場合にのみ機能することを人々は常に理解しています。それは
当たり前のことです

3
@JFSebastian:その通りです、それは保証されていません、またはPOSIX標準によって強制されています。それは、後のIEEEバージョンの1つに環境に関するものが含まれていたためだと思いました。どちらの方法でも:いいえ、/usr/bin/env広く採用されている(普遍的に?)ルール以外の標準では保証されていません...
エリアスヴァンウーテゲム

6
virtualenvを使用している場合、#!/ usr / local / bin / pythonが存在していても、エラーになります。
nullas '19

6
これに関する1つの問題:PEP394によるとpython、スクリプトがPython 2およびPython 3と互換性がある場合にのみ実行可能ファイルを使用する必要があります。それ以外の場合は、python2およびから適切な選択をポイントする必要がありpython3ます。
amiller27 2017年

67

それは本当にただの好みの問題です。シバンを追加すると、必要に応じてスクリプトを直接呼び出すことができます(実行可能としてマークされている場合)。省略pythonした場合は、手動で呼び出す必要があります。

プログラムの実行の最終結果は、どちらの方法でも影響を受けません。それは手段の単なる選択肢です。


3
それだけです-「正しい」面がないので、どちらをとってもかまいません。それは完全に主観的な決定です。
アンバー

5
他の些細な決定にすぎません。en.wikipedia.org/wiki/Parkinson's_Law_of_Triviality
Amber

2
「python」コマンドなしで直接pythonファイルを実行するにはどうすればよいですか?
Zen

5
@Zenスクリプトにシバン(#!/ usr / bin / env python)を含めたとすると、スクリプトを実行可能にする必要があります。のような何かchmod a+x [your-script].pyがそれを実行可能にして./[your-script.py]、シェルで呼び出すことができます。
skålfyfan

9
GlassGhostによって答えが指摘するように、そこにある味のほかに、それを含めての具体的な利点は:それは、彼らはむしろ、インポートされることを意味していますファイルよりも、実行可能なスクリプトを読んでいることを、ファイルの将来のリーダーに明確になります。シバンは、それらを持つ言語のパブリック/プライベートアクセスコントロール修飾子と同様に、実際の効果だけでなくドキュメントとしても役立ちます。場合によっては、ドキュメントの側面が実際に最も重要になります。
マークアメリー

32

Pythonスクリプトにシバンを入れるべきですか?

シバンをPythonスクリプトに挿入して、次のことを示します。

  • このモジュールはスクリプトとして実行できます
  • python2、python3でのみ実行できるか、それともPython 2/3互換か
  • POSIXでは、python実行可能ファイルを明示的に呼び出さずにスクリプトを直接実行する場合に必要です。

これらは同等に移植可能ですか?最も使用されるフォームはどれですか?

シバンを手動で書く#!/usr/bin/env python場合は、使用しない特別な理由がない限り、常に使用してください。このフォームはWindows(Pythonランチャー)でも理解できます。

注:インストールされているスクリプトは、特定のPython実行可能ファイル(例:/usr/bin/pythonまたは)を使用する必要があります/home/me/.virtualenvs/project/bin/python。シェルでvirtualenvをアクティブにすると、いくつかのツールが壊れるのはよくありません。幸いなことに、正しいシバンは、ほとんどの場合、setuptoolsまたは配布パッケージツールによって自動的に作成されます(Windowsでは、setuptoolsラッパー.exeスクリプトを自動的に生成できます)。

つまり、スクリプトがソースチェックアウト内にある場合は、おそらくが表示され#!/usr/bin/env pythonます。それがインストールされている場合、シバンは特定のpython実行可能ファイルへのパス#!/usr/local/bin/python です(注:後者のカテゴリのパスを手動で記述しないでください)。

、、またはシバンで使用する必要があるかどうかを選択するにはpythonPEP 394-Unixのようなシステムでの「python」コマンドを参照してください。python2python3

  • ... pythonは、Python 2および3の両方とソース互換性のあるスクリプトに対してのみ、シバン行で使用する必要があります。

  • Pythonのデフォルトバージョンの最終的な変更に備えて、Python 2のみのスクリプトは、Python 3とソース互換になるように更新するか、そうでなければpython2shebang行で使用する必要があります。


3
PEPに言及する最初の答えは、十分な賛成票を持っていません。えっ?#!/usr/bin/env pythonそれ自体にPEPはありますか?
binki 2015

使用しないでください#!/usr/bin/env python。「常に使用する」ことを勧めないでください#!/usr/bin/env python。これは、99%のケース(回答に含まれている理由)で行うのは間違っています。
ジェイ・サリバン

1
@JaySullivanソースのチェックアウトとインストールされたスクリプトの違いを理解していますか?私はその提案を支持しています。うまくいきます。
jfs

1
@jfs:私のコメントをもう一度読んだ後、私は自分のポイントをまったく理解できなかったことがわかります。私が言ったのは、ほとんどの人が「python」ではなく「python2」または「python3」を使いたいということです。技術的にOPの質問であったフルパスまたは環境を介して解決するかどうかにかかわらず、あなたは答えました。その点については異論はありません。
ジェイサリバン

@JaySullivan同意する。あなたは答えの中での激励からの引用を読みましたか?同じことを言っています。
jfs

15

Pythonのバージョンが複数あり、スクリプトを特定のバージョンで実行する必要がある場合は、スクリプトを直接実行するときに、適切なバージョンが使用されるようにすることができます。次に例を示します。

#!/usr/bin/python2.7

スクリプトは完全なPythonコマンドラインまたはインポートを介して実行できますが、その場合、シーバンは無視されます。しかし、スクリプトが直接実行される場合、これはシバンを使用する適切な理由です。

#!/usr/bin/env python 通常はより良いアプローチですが、これは特別な場合に役立ちます。

通常、Python仮想環境を確立する#!/usr/bin/env pythonことをお勧めします。その場合、ジェネリックはvirtualenvに対してPythonの正しいインスタンスを識別します。


スペースが原因で失敗するのではないですか?
RandomInsano 2014年

1
@RandomInsano、私はそうは思いません。スペースはかなり一般的であるように見え、受け入れられた使用法としてのこのネットの周りに多くの証拠があります。ただし、スペースなしの方がおそらく標準的な使用法だと思います。
Chris Johnson

1
これは間違いなく正しいです。bashとtcshでテストされました。
RandomInsano 2014年

の結果から、which正常に機能する文字列が得られます。あなたはそれを使用するために内臓のいずれかを心配する必要はありません。
SDsolar 2017年

10

スクリプトを実行可能にする場合は、シバンを追加する必要があります。また、ターゲットプラットフォームで動作するようにシバンを正しいものに変更するインストールソフトウェアを使用してスクリプトをインストールする必要があります。この例は、distutilsとDistributeです。


1
#を変更する必要はありません。その後ライン。これが/ usr / bin / envの目的です。特定のPythonインタープリターに対するハードコーディングは、害を及ぼす可能性があります。別のPythonバージョンのインストールや、ディストリビューションのPythonインストールとカスタムPythonインストールの切り替えに関しては、非常に脆弱です。
2015年

Ubuntuでは、の結果をwhich使用すると、システムコマンドなどで使用されているデフォルトが自動的に選択されます。それは一般的であり、システムはそれを適切なインストールに誘導します。
SDsolar 2017年

9

シバンの目的は、スクリプトをシェルから実行するときに、スクリプトがインタープリターのタイプを認識するようにすることです。ほとんどの場合、そして常にというわけではありませんが、外部でインタープリターを提供することによってスクリプトを実行します。使用例:python-x.x script.py

これはシバン宣言子がなくても機能します。

最初の方がより「移植性がある」理由は、システム実行可能ファイルが存在するすべての宛先を説明/usr/bin/envするPATH宣言が含まれているためです。

注:トルネードはシバンを厳密に使用しておらず、Djangoは厳密に使用していません。アプリケーションのメイン機能の実行方法によって異なります。

また、Pythonによっても異なりません。


8

時々、答えがあまり明確でない場合(つまり、「はい」か「いいえ」かを判断できない場合)、それはそれほど重要ではなく、答え明確になるまで問題を無視できます。

#!唯一の目的は、スクリプトを起動するためです。Djangoは独自にソースをロードして使用します。使用するインタープリターを決定する必要はありません。このように、#!実際にはここでは意味がありません。

通常、モジュールであり、スクリプトとして使用できない場合は、を使用する必要はありません#!。一方、モジュールソースにif __name__ == '__main__': ...は、機能の簡単なテストが含まれていることがよくあります。その後、#!再び意味があります。

使用する理由の1つ#!は、Python 2とPython 3の両方のスクリプトを使用する場合です。これらのスクリプトは、異なるバージョンのPythonで解釈する必要があります。このように、pythonスクリプトを手動で(#!内部なしで)起動するときに何を使用する必要があるかを覚えておく必要があります。このようなスクリプトが混在している場合は、#!内部を使用して実行可能にし、実行可能ファイル(chmod ...)として起動することをお勧めします。

MS-Windowsを使用する場合、#!最近までは意味がありませんでした。Python 3.3は、#!行を読み取り、インストールされているバージョンのPythonを検出し、正しいバージョンまたは明示的に必要なバージョンのPythonを使用するWindows Pythonランチャー(py.exeおよびpyw.exe)を導入しています。拡張機能はプログラムに関連付けることができるため、WindowsでもUnixベースのシステムの実行フラグと同様の動作を得ることができます。


3

最近、Windows 3.xにPython 3.6.1をインストールしたときに、shebang行を処理するはずのPythonランチャーfor Windowsもインストールしました。しかし、Pythonランチャーがこれを行わないことがわかりました。シバン行は無視され、Python 2.7.13が常に使用されました(py -3を使用してスクリプトを実行した場合を除く)。

これを修正するには、Windowsレジストリキーを編集する必要がありましたHKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.File\shell\open\command。これはまだ価値がありました

"C:\Python27\python.exe" "%1" %*

以前のPython 2.7インストールから。このレジストリキーの値を次のように変更しました

"C:\Windows\py.exe" "%1" %*

Pythonランチャーのシバンライン処理は、上記のように機能しました。


2

別のモジュールがインストールされていて、特定のpythonインストールを使用する必要がある場合、shebangは最初は制限されているように見えます。ただし、以下のようなトリックを実行して、最初にシェルスクリプトをシェルスクリプトとして呼び出し、次にpythonを選択することができます。これは非常に柔軟なimoです。

#!/bin/sh
#
# Choose the python we need. Explanation:
# a) '''\' translates to \ in shell, and starts a python multi-line string
# b) "" strings are treated as string concat by python, shell ignores them
# c) "true" command ignores its arguments
# c) exit before the ending ''' so the shell reads no further
# d) reset set docstrings to ignore the multiline comment code
#
"true" '''\'
PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    echo Using preferred python $PREFERRED_PYTHON
    exec $PREFERRED_PYTHON "$0" "$@"
elif [ -x $ALTERNATIVE_PYTHON ]; then
    echo Using alternative python $ALTERNATIVE_PYTHON
    exec $ALTERNATIVE_PYTHON "$0" "$@"
else
    echo Using fallback python $FALLBACK_PYTHON
    exec python3 "$0" "$@"
fi
exit 127
'''

__doc__ = """What this file does"""
print(__doc__)
import platform
print(platform.python_version())

あるいは、おそらく、複数のpythonスクリプト間でのコードの再利用を容易にするために:

#!/bin/bash
"true" '''\'; source $(cd $(dirname ${BASH_SOURCE[@]}) &>/dev/null && pwd)/select.sh; exec $CHOSEN_PYTHON "$0" "$@"; exit 127; '''

そしてselect.shは:

PREFERRED_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python
ALTERNATIVE_PYTHON=/Library/Frameworks/Python.framework/Versions/3.6/bin/python3
FALLBACK_PYTHON=python3

if [ -x $PREFERRED_PYTHON ]; then
    CHOSEN_PYTHON=$PREFERRED_PYTHON
elif [ -x $ALTERNATIVE_PYTHON ]; then
    CHOSEN_PYTHON=$ALTERNATIVE_PYTHON
else
    CHOSEN_PYTHON=$FALLBACK_PYTHON
fi

1
このようなポリグロットが一般的に良い習慣であるかどうかはわかりませんが、これは確かに非常に興味深いアプローチであり、おそらくここで最も柔軟な答えです。
Ryan Amos

1
とてもかっこいい。あなたがそれができるとは思いませんでした
user2233949

1

回答:コマンドラインで実行可能なスクリプトにする場合のみ。

手順は次のとおりです。

まず、使用する適切なシバン文字列を確認します。

which python

その出力を取得し、最初の行に(シバン#!で)追加します。

私のシステムでは次のように応答します:

$which python
/usr/bin/python

したがって、シバンは次のようになります。

#!/usr/bin/python

保存後も、Pythonは最初の行をコメントとして表示するため、以前と同じように実行されます。

python filename.py

コマンドにするには、コピーして.py拡張子をドロップします。

cp filename.py filename

これが実行可能であることをファイルシステムに伝えます。

chmod +x filename

それをテストするには、以下を使用します。

./filename

ベストプラクティスは、ファイルを$ PATHのどこかに移動することです。そのため、入力する必要があるのはファイル名自体だけです。

sudo cp filename /usr/sbin

そうすれば、どこでも機能します(ファイル名の前の./なし)


これがベストプラクティスであることは疑わしく、GlassGhostのソリューションを使用することを強くお勧めします
コリディア

私はこれが役に立ち、それは私にとって美しく機能しました。これは十分に説明されました。ただし、これがベストプラクティスではない理由を示すコメントをいただければ幸いです。私は学びたいと思っています。
チャールズカリエール

0

絶対パスと論理パス:

これは、移植性に関して、Pythonインタープリターへのパスを絶対パスにするか論理パス(/usr/bin/env)にするかという問題です。

これと証明を支援することなく、一般的な方法で問題について話し、他のスタックサイト上の他の回答に遭遇、私はいくつかの本当に、行ってきました本当に上のこの非常に疑問に、粒状のテスト&分析をunix.stackexchange.com。ここにその答えを貼り付けるのではなく、比較分析に興味のある人にその答えを指摘します。

https://unix.stackexchange.com/a/566019/334294

Linuxエンジニアとしての私の目標は、常に開発者クライアントに最適で最適化されたホストを提供することです。そのため、Python環境の問題は、確かな答えを本当に必要としていました。テスト後の私の見解は、シバンの論理パスは(2)オプションの方が優れているというものでした。


-3

最初に使用

which python

これにより、Pythonインタープリター(バイナリー)が存在する場所として出力が提供されます。

この出力は次のようなものになります

/usr/bin/python

または

/bin/python

次に、シバン線を適切に選択して使用します。

一般化するには、以下を使用できます。

#!/usr/bin/env

または

#!/bin/env

3
これはおそらく他のシステムに移植できません。#!/usr/bin/envあなたにとって正しい選択をします。
fragmentedreality

これが、whichコマンドを使用する理由です。特定のシステムの正しい文字列を返します。
SDsolar 2017年

1
...そして毎回スクリプトが別のマシン上で実行される、あなたが実行しwhich python、再び、現在のシェバングからの出力が異なる場合、スクリプトを変更
fragmentedreality

2
-1これは、最も壊れやすいソリューションです。Pythonスクリプトが記述されているシステムに対してのみ正しいことが保証されています。移植性のために#!/ usr / bin / env python3を使用してください
Mylesは、2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.