web-dev-qa-db-ja.com

pythonから `bash`または`。/ `を使用してbashスクリプトを実行する必要がありますか?

このようなbashスクリプトを実行するPythonスクリプトを作成しました。

cmd = subprocess.Popen(['bash', 'script.sh'])

chmodで実行権限を設定していませんが、その方法でスクリプトを実行します。ターミナルbash script.shに書き込むこともできますが、動作は同じです。この./のように、ドットスラッシュ./script.shを前に付けることでスクリプトを実行できることを知っています。

それで、Pythonスクリプトでどの方法を使うべきでしょうか?どうして?

6
answerSeeker

まず、./script.shのドットに関して、これはscript.shが作業ディレクトリにあることを示します。これは、「このディレクトリでscript.shを探す」などのことを意味します。これはドットスラッシュと呼ばれ、よく説明されています ここ

次の3つのオプションがあります。

  1. ユーザーがPythonスクリプトを実行するときに、ユーザーのcurrent作業ディレクトリにある場合にのみ実行するようにファイルを制限する場合、次に、ドットスラッシュを使用します。ただし、これは最良のアイデアとは思えません。ほとんどの場合、例外になります。

  2. Pythonスクリプトと同じディレクトリにある場合にのみ実行するようにシェルスクリプトを制限する場合は、 Pythonスクリプトのディレクトリを調べる必要があります。 そして、スクリプトの名前の前に付けます。

  3. シェルスクリプトをPATHの他の場所に配置する場合は、ドットスラッシュを使用しないでください。

現在、Popenコンストラクターへの引数として「bash」を送信することは、好みの問題のようです。引数として送信したくない場合は、シェルスクリプトに Shebang を追加する必要があります。 #!/bin/bashand実行許可を追加する必要があります。これらは完全に受け入れられることです。

この方法で行う利点の1つは、後でシェルインタープリターを変更した場合、Pythonスクリプトの数を知っているスクリプトの呼び出しをすべて変更する必要がないことです。

そして、次のようなスクリプトを呼び出すことができます。

cmd = subprocess.call('script.sh')
# or
cmd = subprocess.call(sdir + 'script.sh')
# Where sdir stands for the script's directory,
# which you would need to find before, as in option #2.

注:

スクリプトが正常にシバンなしで実行された場合でも(その場合、Debianベースのディストリビューションでは ダッシュではなくダッシュ によって実行されます)、pythonこのように、失敗し、errno 8(errno.ENOEXEC)でOSError例外が発生します。

本当に必要な場合は、Popenを使用

10
Samuel