subprocess.Popen未正确解析参数
我最近在玩一个叫做 subprocess.Popen
的东西,想用它来执行一个程序,但一直没找到正确的方式来传递参数。
这里有一段简化的代码,应该可以执行我的程序:
subprocess.Popen(shlex.split('dflat --portfolio jumpy --seed 1 --tables -n semi --elimination min-degree -e edge --default-join -p ../test_encodings/exchange.lp'))
这个 shlex.split(...)
的输出是:
['dflat', '--portfolio', 'jumpy', '--seed', '1', '--tables', '-n', 'semi', '--elimination', 'min-degree', '-e', 'edge', '--default-join', '-p', '../test_encodings/exchange.lp']
不过被调用的程序出错了,告诉我需要提供一个程序(-p
选项),而我确实在上面提供了。
但是从命令行直接运行这个命令是完全没问题的。
2 个回答
0
你提到的命令看起来是对的。确保你的代码完全一样,没有任何改动。
我猜可能是 --default-join
这个选项把 -p
的参数给吃掉了。你可以试试把 --default-join
放到命令的最后面。
另外,确保你是从正确的文件夹启动脚本的。-p
的值是相对路径,要检查一下文件是否能访问。
1
如果你能提供一个其他人可以运行的示例,那就太好了(而不是需要非标准的 dflat
程序的东西)。
一般来说,你发的这个方法应该是可行的。不过,自己手动拆分数组会更常见,也更不容易出错,读起来也更清晰。
subprocess.Popen([
'dflat',
'--portfolio', 'jumpy',
'--seed', '1',
'--tables',
'-n', 'semi',
'--elimination', 'min-degree',
'-e', 'edge',
'--default-join',
'-p', '../test_encodings/exchange.lp'])
手动拆分的好处是,你可以把每个需要参数的选项和它的参数放在同一行,这样更容易理解。如果你的参数里有空格、引号等字符,这样做也能避免一些引号的问题。使用 shlex.split()
可以解决一些问题,但如果你直接把字符串作为第一个参数并使用 shell=True
,你可能会遇到更多麻烦,虽然这样做会稍微少一些问题,因为你不需要担心内容被误解为重定向字符、管道、复合命令、命令间接等。