2014-06-12 30 views
2

我想执行这个linux命令为什么这个linux命令在使用python执行时不工作?

“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 
+0

相关:https://stackoverflow.com/questions/295459/how-do-i-use-subprocess-popen-to-connect-multiple-processes-by-pipes – OozeMeister

+0

你尝试调用子以及参数列表 – c24b

回答

3

subprocess.call执行的可执行文件。您是而不是将路径传递给可执行文件作为参数,您传递的是shell命令行。

要执行shell命令,您必须明确声明您希望通过在参数列表中传递shell=True来执行shell中的命令。 请注意,将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']) 

注意引号是如何(但是没有执行shell扩展!)

+0

值得注意的是:如果外部用户可以以任何方式改变发给subprocess.call()的命令,请小心使用'shell = True'' – OozeMeister

+0

@OozeMeister这就是我所说的“使用'shell = True'与用户提供的命令可能是安全危险。“ – Bakuriu

1

你正在传递一个shell命令,所以Python应该调用一个shell来解析和运行你的命令。但是您要让Python调用名称为cat info.txt | mailx -s "DEVSETUP" [email protected]的命令,即在命令搜索路径中应该有一个可执行的名称 - 并且不存在这样的命令。

subprocess.call支持构造函数Popen的所有关键字参数。您可以传递关键字参数shell=True来指示您拥有的是一些shell代码,而不是可执行文件的名称。

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

然而,提防的mailid值将在shell代码片段,如果它包含shell特殊字符,如[email protected] (Bob Smith)Bob Smith <[email protected]>这将打破内插。您应该安排引用mailid中的任何特殊字符。

您发布的命令的另一个问题是如果在读取info.txt时发生任何错误,它将不会被检测到。您可以弥补这方面通过避免无用的使用cat

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

鉴于命令很简单,你不需要在所有调用shell。如果没有外壳参与,则不需要担心引用。您可以轻松地让Python打开info.txt文件供阅读。

body_file = open("info.txt") 
status = subprocess.call(["mailx", "-s", "DEVSETUP", mailid], stdin=body_file) 
body_file.close() 
if status != 0: 
    … handle mailx failure … 
相关问题