import subprocess
retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"])
これらの2行を実行すると、正確にこれを実行しますか?:
/home/myuser/go.sh abc.txt xyz.txt
なぜこのエラーが発生するのですか?しかし、go.shを通常どおり実行すると、そのエラーは発生しません。
File "/usr/lib/python2.6/subprocess.py", line 480, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
raise child_exception
OSError: [Errno 8] Exec format error
OSError:[Errno 8] Execフォーマットエラー
これは、/home/myuser/go.sh
を実行しようとしたときにオペレーティングシステムによって報告されたエラーです。
#!
のShebang(go.sh
)行が無効であるように見えます。
シェルから実行されるがPopen
からは実行されないサンプルスクリプトを次に示します。
#\!/bin/sh
echo "You've just called $0 $@."
最初の行から\
を削除すると、問題が修正されます。
コードを次のように変更します。
retcode = subprocess.call(["/home/myuser/go.sh", "abc.txt", "xyz.txt"], Shell=True,)
「Shell = True」に注意してください
差出人: http://docs.python.org/library/subprocess.html#module-subprocess
Unixの場合、Shell = Trueの場合:argsが文字列の場合、シェルを介して実行するコマンド文字列を指定します。つまり、文字列は、シェルプロンプトで入力したときとまったく同じようにフォーマットする必要があります。
私は最近、次のようなスクリプトでこの問題に遭遇しました。
% cat /tmp/test.sh
<-- Note the empty line
#!/bin/sh
mkdir /tmp/example
スクリプトはコマンドラインから正常に実行されましたが、
OSError: [Errno 8] Exec format error
経由で実行された場合
subprocess.Popen(['/tmp/test.sh']).communicate()
(もちろん、解決策は空の行を削除することでした)。
In :call??
Signature: call(*popenargs, **kwargs)
Source:
def call(*popenargs, **kwargs):
"""Run command with arguments. Wait for command to complete, then
return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:
retcode = call(["ls", "-l"])
"""
return Popen(*popenargs, **kwargs).wait()
File: /usr/lib64/python2.7/subprocess.py
Type: function
呼び出しはPopenを呼び出すだけで、wait()メソッドを使用してpopenargsが完了するのを待ちます
はい、シェルスクリプトを呼び出し、スクリプトが完了するのを待って、終了ステータスを収集し、そのstdin、stdout、およびstderrをPythonプロセスから継承するだけであれば、これでまったく問題ありません。これらの要素のいずれかをより細かく制御する必要がある場合は、より一般的な subprocess.Popen
を使用しますが、それ以外の場合は問題ありません。
subprocess.call
を使用して1行のスクリプトを呼び出そうとしたときに、MacOSでこのエラーが発生しました。コマンドラインから呼び出されたとき、スクリプトは正常に実行されました。シバンライン#!/usr/bin/env sh
を追加した後、subprocess.call
を介して正常に実行されました。
シェルには実行可能とマークされたテキストファイルのデフォルトのエグゼキュータがありますが、subprocess.Popen
にはありません。
はい、これは何かを実行するための好ましい方法です。
シェルによって評価される引数文字列としてではなく、配列(内部でexec()スタイルの呼び出しで使用されます)を介してすべての引数を渡すため、シェルコマンドの挿入が不可能であるため、非常に安全です。