在subprocess.Popen中使用多变量和%dict()

1 投票
3 回答
972 浏览
提问于 2025-04-18 12:57

我有很多图片需要优化,并且想把所有输入的名字和输出的名字整理到一个csv文件里。之前我用AWK来做这种工作,但现在我想换成用Python的.Popen方法。

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'

我该怎么把所有这些变量传递给Popen呢?

提前谢谢你!

3 个回答

0

为了在 innameoutname 文件名中允许空格(或者其他特殊字符),从一开始就把命令构建成一个列表:

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

我会把@Alp的回答改成:

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

这样做可以让你关闭Popen,同时也能读取输入。

os.setsid的作用更像是C语言中的execfork

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

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

0

你遇到了两个问题。首先,你需要在分割字符串之前进行插值操作。因为你在插值之前就把命令字符串分割了,所以在

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)

其次,你需要对那些想要作为字面意思的%符号进行转义。你应该这样做:

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)

撰写回答