【问题标题】:multi variables in subprocess.Popen with %dict()subprocess.Popen 中的多个变量,使用 %dict()
【发布时间】:2014-09-02 04:44:21
【问题描述】:

我有很多图像要优化和排序 csv 文件中的所有输入名称和输出名称。以前,我使用 AWK 来完成此类工作,但现在我更喜欢使用 .Popen 方法切换到 python。

import subprocess
import shlex
cmdc2d='c2d %(inname)s -clip 1% 99% -type short -stretch 1% 99% 0 255 -o %(outname)s'
argscmd=shlex.split(cmdc2d)
subprocess.Popen(argscmd%dict(inname='test1.png',outname='test1-2.png'))

输出给了我一个错误

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for %: 'list' and 'dict'

如何将所有这些变量传递到 Ponpen []?

提前谢谢你!

【问题讨论】:

    标签: python variables awk popen


    【解决方案1】:

    你有两个问题。首先,您需要在拆分字符串之前执行插值。因为你在插值之前拆分了命令字符串,所以第一个操作数为% in

    argscmd%dict(inname='test1.png',outname='test1-2.png')
    

    是一个列表,% 不是列表和字典的定义操作。您需要 % 的第一个操作数是一个字符串。尝试类似:

    import subprocess
    import shlex
    cmdc2d='c2d %(inname)s -clip 1% 99% -type short -stretch 1% 99% 0 255 -o %(outname)s'
    argscmd=shlex.split(cmdc2d % dict(inname='test1.png',outname='test1-2.png'))
    subprocess.Popen(argscmd)
    

    其次,您需要转义 % 符号,这些符号旨在成为文字 %s。你会想要这个:

    import subprocess
    import shlex
    cmdc2d='c2d %(inname)s -clip 1%% 99%% -type short -stretch 1%% 99%% 0 255 -o %(outname)s'
    argscmd=shlex.split(cmdc2d % dict(inname='test1.png',outname='test1-2.png'))
    subprocess.Popen(argscmd)
    

    【讨论】:

    • 非常感谢,它运行良好。那么我将把 csv 带入脚本中。
    • @user3817800: 如果innameoutname 包含空格,则shlex.split() 在此处中断。你可以create the list directly instead
    【解决方案2】:

    我会将@Alp 的答案更改为:

    subprocess.Popen(argscmd, shell=True, stdout=subprocess.PIPE, preexec_fn=os.setsid)

    这将允许您关闭 Popen 并读取输入。 os.setsid 更像是execfork 中的C

    https://docs.python.org/2/library/subprocess.html#subprocess.PIPE

    https://docs.python.org/2/library/os.html#os.setsid

    【讨论】:

    • 自从我开始阅读 Popen() 以来,几乎每个人都说 shell=True 是不安全的。我暂时犹豫要不要使用它...对不起
    • 错了。不要同时使用列表参数 (argscmd) 和 shell=True。在大多数情况下,字符串参数应与shell=True 一起使用,而不是列表。虽然我没有看到任何迹象表明在 OPs 情况下shell=True 是必要的。
    【解决方案3】:

    要在innameoutname 文件名中允许空格(或其他特殊字符),请从头开始将命令构造为列表:

    cmd = ['c2d', inname]
    cmd += '-clip 1% 99% -type short -stretch 1% 99% 0 255 -o'.split()
    cmd += [outname]
    p = subprocess.Popen(cmd)
    ...
    

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 1970-01-01
      • 2016-04-24
      • 2022-12-31
      • 2018-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多