特定のPythonインストールで実行する必要があるPythonスクリプトがあります。それが実行されるようにシバンを作成する方法はあり$FOO/bar/MyCustomPython
ますか?
特定のPythonインストールで実行する必要があるPythonスクリプトがあります。それが実行されるようにシバンを作成する方法はあり$FOO/bar/MyCustomPython
ますか?
回答:
シバングラインは非常に限られています。多くのUNIXバリアント(Linuxを含む)では、コマンドと1つの引数という2つの単語しか使用できません。多くの場合、長さの制限もあります。
一般的な解決策は、小さなシェルラッパーを記述することです。Pythonスクリプトfoo.py
に名前を付け、シェルスクリプトを横に置いてfoo.py
呼び出しますfoo
。このアプローチでは、Pythonスクリプトに特定のヘッダーは必要ありません。
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
別の魅力的なアプローチは、上記のようなラッパースクリプトを記述#!/path/to/wrapper/script
し、Pythonスクリプトのシェバン行として配置することです。ただし、ほとんどの大学はシバングスクリプトのチェーンをサポートしていないため、これは機能しません。
にある場合MyCustomPython
は、検索に$PATH
使用できますenv
。
#!/usr/bin/env MyCustomPython
import …
さらに別のアプローチは、スクリプトを有効なシェルスクリプト(適切なPythonインタープリターをロードする)とターゲット言語(ここではPython)の有効なスクリプトの両方にすることです。これには、ターゲット言語用のこのような二重言語スクリプトを作成する方法を見つける必要があります。Perlでは、これはとして知られていif $running_under_some_shell
ます。
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Pythonで同じ効果を実現する1つの方法を次に示します。シェル内"true"
のtrue
ユーティリティは、引数(2つの1文字の文字列:
と'
)を無視し、真の値を返します。Pythonでは"true"
、ブール値として解釈されるときにtrueにif
なる文字列です。したがって、これは常にtrueであり、文字列リテラルを実行する命令です。
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
PYTHONPATH
env変数を編集し、ルートアクセス権のないシステムでCGIスクリプトの非標準の場所からモジュールをロードしました。命の恩人。再度、感謝します。
シバン行は変数展開さ$FOO/MyCustomPython
れないため、dollar-FOO-という名前の実行可能ファイルを検索するために使用することはできません。
別の方法としては、シェバンがシェルスクリプトをインタープリターとして指すようにして、このシェルスクリプトが環境変数を使用して正しいものを見つけて実行することができます。
例:次のコンテンツmypython.sh
で/usr/local/bin
(またはのその他のディレクトリ$PATH
)にスクリプトを作成します。
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
次に、このshebang行を使用して、PythonスクリプトをMyCustomPython
viaで実行できますmypython.sh
。
#!/usr/bin/env mypython.sh
$python
しないでください$PYTHON
-慣例により、環境変数(大文字のPAGER、EDITOR、SHELL ... $PYTHON
は環境変数ではありません)および内部シェル変数(BASH_VERSION、RANDOM、...)を大文字にします。他のすべての変数名には、少なくとも1つの小文字を含める必要があります。この規則により、環境変数および内部変数が誤ってオーバーライドされるのを防ぎます。また、スクリプトに拡張機能を使用しないでください。スクリプトは、実行可能な新しいコマンドを定義します。通常、コマンドには拡張機能はありません。
最初に、Pythonのバージョンが既にインストールされている標準Python(追加モジュールなど)とどのように異なるかを判断し、プログラムの開始時にPythonの呼び出し方法を切り替えます:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
これにより、他のPythonインスタンスからプログラムを呼び出すことができます。システムのpythonにモジュールとしてインポートできないビルトインsqlライブラリを持つインスタンスに対しても同様のことを行います。
あなたが交換することができる場合$FOO
には$FOO/bar/MyCustomPython
、具体的なパスオプションで、あなたが言うことができるenv
、直接カスタムを設定することで、カスタムPythonのバージョンを検索するシェバング行PATH
、それには。
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
編集:PATH値の割り当てを引用符なしでのみ動作するようです:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
ように展開する方がPATH=$PATH:/path/to/whatever...