【问题标题】:Python subprocess.Popen error handling with shell=True/False issuesPython subprocess.Popen 错误处理与 shell=True/False 问题
【发布时间】:2017-10-18 01:28:13
【问题描述】:

我正在尝试对以下代码进行一些错误处理。

在 subprocess.Popen...... 行中,如果 shell=True,如果给出了正确的文件名,脚本将加密,但是没有具有该名称的文件,不会打印错误代码,但确实如此在终端上显示为没有现有的文件/目录。

如果我运行 shell=False,则我无法加密文件,但会打印错误消息。

谁能解释我做错了什么?正如我在这里查看了不同的帖子,但我仍然不明白为什么它不起作用。我的猜测是它与脚本的 shell=True 部分有关。

SrcDIR ="/home/test/testsource/"

DstDIR ="/home/test/testdest/"

try:
    subprocess.Popen(["openssl aes-128-cbc -salt -in " + SrcDIR + str(var1) + " -out " + DstDIR + "enc." + str() + " -k " + str(var2)], shell=True)
    output3 = ("file " + str(var1) + "created")
    print(output3)
except IOError as reason2:
    errormsg = ("Error encrypting file due to: \n" + str(reason2))
    print(errormsg)

【问题讨论】:

    标签: python python-3.x subprocess popen ioerror


    【解决方案1】:

    如果将shell 参数设置为False,则args 参数将变为字符串的序列,而不是单个字符串:第一个args 元素是要运行的程序,后续元素是该程序的参数,例如(如果我正确理解您的代码):

    subprocess.Popen \
      (
        [
            "openssl", "aes-128-cbc", "-salt",
            "-in", os.path.join(SrcDIR, var1),
            "-out", os.path.join(DstDIR, "enc." + var1),
            "-k", var2
        ]
      )
    

    这也比尝试使用 shell = True 传递单个命令字符串要好,因为这样您就不必提防对 shell 具有特殊含义的字符。

    【讨论】:

    • 感谢您的帮助,现在我可以使用 shell=False 运行加密部分。但是,我仍然遇到错误检查问题。即使文件不存在,子进程仍将执行并打印创建的文件。你有什么想法吗?
    • 试试subprocess.check_output 便利例程,它可以一次性创建 Popen 对象、收集其输出并检查错误。
    • 或者如果您不想要命令的输出,请改用subprocess.check_call
    • 嘿,如果你有时间,还有一个简短的问题。是否可以使用 subprocess.check_output 为 if 语句返回错误代码?例如 if subprocess.check_output == error code 0 或类似的东西。本质上,如果有错误则输出错误推理,如果没有错误则继续执行 subprocess.Popen。
    • 如果子进程打印出任何错误消息,那么大概用户会看到。这就是你所说的“推理”吗?
    【解决方案2】:

    即使使用 shell=True,如果第一个参数是字符串列表,它也会将其解释为调用的参数列表。还有其他原因可能不想使用 shell=True,但不需要使用 shell=True 来使用参数列表不是其中之一。

    除此之外,Lawrence D'Oliveiro 在使用列表与使用单个字符串的好处方面是正确的。

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 2020-01-22
      • 2013-12-25
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多