2

このLinuxコマンドを実行したい

"cat cflow_image.py | mailx -s "CFLOW コピー" foo@.foo.com". 私の要件は、python スクリプトでこのコマンドを使用することです。これを達成するために subprocess モジュールを使用しています。

これを行うための私のコードは次のとおりです。

def send_mail(mailid): 
   # This is mail the testbed info to the user
   mailid = args.mailID 
   print "* INFO file will be sent to your mailid *"
   subprocess.call("cat info.txt | mailx -s \"DEVSETUP\" {0}").format(mailid)

実行時のエラーは次のとおりです。

Traceback (most recent call last):
  File "dev-installer.py", line 243, in <module>
    send_mail(args.mailID)
  File "dev-installer.py", line 204, in send_mail
    subprocess.call("cat info.txt | mailx -s \"DEVSETUP\" {0}").format(mailid)
  File "/sw/packages/python/2.7.4/lib/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/sw/packages/python/2.7.4/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/sw/packages/python/2.7.4/lib/python2.7/subprocess.py", line 1308, in _execute_child
4

2 に答える 2

3

subprocess.call実行可能ファイルを実行します。実行可能ファイルへのパスを引数として渡すのではなく、シェルコマンド ラインを渡します。

シェルコマンドを実行するshell=Trueには、引数リストを渡して、シェルでコマンドを実行することを明示的に指定する必要があります。shell=Trueユーザー提供のコマンドを使用すると、セキュリティ上の問題が発生する可能性があることに注意してください。

また、使用していないshell=True場合 (指定しない場合など) は、既に解析された引数リストを表す文字列のリストを引数として渡す必要があることに注意してください。例えば:

subprocess.call('ls -l')

という名前のコマンドを実行しようとしls -lますが、その名前の実行可能ファイルが にない場合、おそらく失敗しますPATH

subprocess.call(['ls', '-l'])

ls引数で実行可能ファイルを呼び出します-l

そのようなリストを手動で書きたくない場合はshlex.split、「コマンドライン」を解析するために使用します:

subprocess.call(shlex.split('executable arg1 arg2 --option1 --option2 "string argument"'))

呼び出しは次のようになります。

subprocess.call(['executable', 'arg1', 'arg2', '--option1', '--option2', 'string argument'])

引用符がどのように適切に処理されたかに注意してください (ただし、シェル展開は実行されません!)

于 2014-06-12T13:45:04.873 に答える
1

シェル コマンドを渡しているので、Python はコマンドを解析して実行するシェルを呼び出す必要があります。しかし、Python に という名前のコマンドを呼び出すように指示しています。cat info.txt | mailx -s "DEVSETUP" foo@.foo.comつまり、コマンド検索パスにその名前の実行可能ファイルが存在する必要がありますが、そのようなコマンドは存在しません。

subprocess.callPopenコンストラクターのすべてのキーワード引数をサポートします。キーワード引数shell=Trueを渡して、実行可能ファイルの名前ではなく、シェル コードであることを示すことができます。

subprocess.call("cat info.txt | mailx -s \"DEVSETUP\" {0}".format(mailid),
                shell=True)

ただし、 の値はシェル スニペットで補間されることに注意してください。これは、や などmailidのシェルの特殊文字が含まれていると壊れます。に存在する特殊文字を引用するように手配する必要があります。bob@example.com (Bob Smith)Bob Smith <bob@example.com>mailid

あなたが投稿したコマンドのもう1つの問題は、読み取り中にエラーが発生した場合info.txt、それが検出されないことです。の無駄な使用を避けることで、これを修正できますcat

subprocess.call("<info.txt mailx -s \"DEVSETUP\" {0}".format(mailid),
                shell=True)

コマンドが単純であるため、シェルを呼び出す必要はまったくありません。シェルが関与しない場合は、引用について心配する必要はありません。info.txt読み取り用に Python でファイルを簡単に開くことができます。

body_file = open("info.txt")
status = subprocess.call(["mailx", "-s", "DEVSETUP", mailid], stdin=body_file)
body_file.close()
if status != 0:
    … handle mailx failure …
于 2014-06-12T14:47:07.593 に答える