繁体   English   中英

为什么使用python执行时此linux命令不起作用?

[英]why is this linux command not working when executed using python?

我想执行这个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

subprocess.call执行一个可执行文件。 没有传递可执行文件的路径作为参数,而是传递了Shell命令行。

要执行shell命令,必须通过在参数列表中传递shell=True来明确声明要在shell中执行命令。 请注意,将shell=True与用户提供的命令一起使用可能会带来安全隐患。

还要注意,当您使用shell=True (例如,当您不指定它时),您应该传递一个字符串列表作为参数,以表示已经解析的参数列表。 例如:

subprocess.call('ls -l')

将尝试执行名为ls -l的命令,如果您在PATH没有具有该名称的可执行文件,则可能会失败,而:

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

将使用参数-l调用ls可执行文件。

如果您不想手动编写此类列表,请使用shlex.split解析“命令行”:

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

将导致通话:

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

请注意如何正确处理引号(但是不执行外壳扩展!)

您正在传递一个shell命令,因此Python应该调用一个将解析并运行命令的shell。 但是,您要告诉Python调用名称为cat info.txt | mailx -s "DEVSETUP" foo@.foo.com的命令cat info.txt | mailx -s "DEVSETUP" foo@.foo.com 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。 如果不涉及任何外壳,则无需担心引用。 您可以轻松地使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 …

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM