【问题标题】:Am I using system call/subprocess call correctly?我是否正确使用系统调用/子进程调用?
【发布时间】:2019-02-27 20:54:15
【问题描述】:

此代码在运行时失败:

import datetime
import subprocess

startdate = datetime.datetime(2010,4,9)
for i in range(1): 
    startdate += datetime.timedelta(days=1)

enddate = datetime.datetime(2010,4,10)
    for i in range(1): 
        enddate += datetime.timedelta(days=1)

subprocess.call("sudo mam-list-usagerecords -s \"" + str(startdate) + "\" -e \"" + str(enddate) + " --format csv --full")

程序运行时出现以下错误:

  File "QuestCommand.py", line 12, in <module>
subprocess.call("sudo mam-list-usagerecords -s \"" + str(startdate) + "\" -e \"" + str(enddate) + " --format csv --full")
  File "/usr/lib64/python2.7/subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
  File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception

我已经用其他方式多次运行此代码,更改引号等。我对系统调用和使用 HPC 分配数据库相当陌生。我被卡住了,如果有人可以帮助我解决这个问题,那将非常有帮助。

谢谢!

【问题讨论】:

  • 我建议先从命令行运行预期的命令,然后将其转换为 python。 =)

标签: python subprocess system allocation hpc


【解决方案1】:

如果可能,传递一个包含您的命令名称及其参数的列表

subprocess.call(["sudo", "mam-list-usagerecords",
                 "-s", str(startdate),
                 "-e", str(enddate),
                 "--format", "csv",
                 "--full"])

这样就无需知道 shell 将如何处理命令行。

【讨论】:

    【解决方案2】:

    当我第一次开始使用一些子流程方法时,我遇到了一些相同的问题。

    尝试像这样运行您的代码:

    import datetime
    import subprocess
    import shlex
    
    startdate = datetime.datetime(2010, 4, 9) + datetime.timedelta(days=1)
    enddate = datetime.datetime(2010, 4, 10) + datetime.timedelta(days=1)
    command = (
        "sudo mam-list-usagerecords -s "
        + str(startdate)
        + "-e"
        + str(enddate)
        + " --format csv --full"
    )
    
    print(command)
    print(type(command))
    print(shlex.split(command))
    subprocess.call(shlex.split(command))
    

    输出:

    sudo mam-list-usagerecords -s 2010-04-10 00:00:00-e2010-04-11 00:00:00 --format csv --full

    类'str'

    ['sudo', 'mam-list-usagerecords', '-s', '2010-04-10', '00:00:00-e2010-04-11', '00:00:00' , '--format', 'csv', '--full']

    (命令输出已编辑。)

    当 kwarg shell 设置为默认值 False 时,命令可能必须是 shlex.split 所做的集合。

    args 应该是一系列程序参数或单个字符串。默认情况下,如果 args 是一个序列,则要执行的程序是 args 中的第一项。如果 args 是字符串,则解释取决于平台,如下所述。有关与默认行为的其他差异,请参阅 shell 和可执行参数。除非另有说明,否则建议将 args 作为序列传递。

    Popen constructor

    在我在文档中找到这个问题之前,这个问题一直让我感到困惑。

    【讨论】:

    • 不要创建一个你将要拆分的字符串;定义一个列表。这样,您必须确保正确引用内容以使最终字符串正确拆分。
    • 如果你知道你的startdateenddate 字符串可以包含哪些字符,这可能会很好用,但是当替换任意字符串时它会非常失败,这些字符串本身可以包含文字引号。因此,这通常是一种不安全的做法。
    • ...正如您自己的报价所说,“建议将 args 作为序列传递”。显式生成该序列(而不是使用shlex.split)可确保拆分准确地发生在开发人员想要的位置,而不是其他任何地方。
    • 我从问题中复制并粘贴了字符串连接。事实上,有更强大的方法来创建命令。关键是shlex.split 是在需要序列时拆分命令字符串的方法。 command 是一个字符串。
    • @DMfll, ...当需要序列时并且您的输入是字符串,但这里不是这种情况——用户没有提供单个字符串作为配置值;该值完全是在代码中生成的,所以不妨先把command 生成为一个列表。
    猜你喜欢
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 2022-01-02
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多