我想执行这个linux命令
“cat cflow_image.py | mailx -s”CFLOW Copy“foo @ .foo.com”。我的要求是在python脚本中使用此命令。我正在使用子进程模块来实现此目的。
这是我执行此操作的代码,
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 :(得分: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
来解析&#34;命令行&#34;:
subprocess.call(shlex.split('executable arg1 arg2 --option1 --option2 "string argument"'))
将导致通话:
subprocess.call(['executable', 'arg1', 'arg2', '--option1', '--option2', 'string argument'])
注意如何正确处理引号(但不执行shell扩展!)
答案 1 :(得分:1)
您正在传递一个shell命令,因此Python应该调用一个解析并运行命令的shell。但是你告诉Python调用一个名为cat info.txt | mailx -s "DEVSETUP" foo@.foo.com
的命令,即命令搜索路径上应该有一个可执行文件 - 并且不存在这样的命令。
subprocess.call
支持Popen
构造函数的所有关键字参数。您可以传递关键字参数shell=True
以指示您拥有的是一些shell代码而不是可执行文件的名称。
subprocess.call("cat info.txt | mailx -s \"DEVSETUP\" {0}".format(mailid),
shell=True)
但是,请注意mailid
的值将在shell代码段中进行插值,如果它包含shell特殊字符,则会在bob@example.com (Bob Smith)
或Bob Smith <bob@example.com>
中中断。您应该安排引用mailid
中出现的任何特殊字符。
您发布的命令的另一个问题是,如果在阅读info.txt
时发生任何错误,则无法检测到该错误。您可以通过避免无用地使用cat
:
subprocess.call("<info.txt mailx -s \"DEVSETUP\" {0}".format(mailid),
shell=True)
鉴于该命令很简单,您根本不需要调用shell。如果不涉及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 …