Python 使用包含引号的参数的subprocess.run
我尝试运行的命令如下所示:Python 使用包含引号的参数的subprocess.run,python,python-3.x,Python,Python 3.x,我尝试运行的命令如下所示: xvfb run--auto-servernum--server args=“-screen 0 640x480x24”--错误文件=/dev/stdout/opt/myExecutable 这就是我在Python3中所做的: args=['xvfb-run'、'-auto-servernum'、'-server args=“-screen 0 640x480x24”、'-error file=/dev/stdout'、'/opt/myExecutable'] 命令
xvfb run--auto-servernum--server args=“-screen 0 640x480x24”--错误文件=/dev/stdout/opt/myExecutable
这就是我在Python3中所做的:
args=['xvfb-run'、'-auto-servernum'、'-server args=“-screen 0 640x480x24”、'-error file=/dev/stdout'、'/opt/myExecutable']
命令=''.join(xvfbArgs)
打印(f'Command:{Command}')
子流程运行(xvfbArgs)
我得到以下信息:
Unrecognized option: "-screen
use: X [:<display>] [option]
...
segfault
...
Command: xvfb-run --auto-servernum --server-args="-screen 0 640x480x24" --error-file=/dev/stdout /opt/myExecutable
无法识别的选项:“-屏幕
使用:X[:][选项]
...
断层
...
命令:xvfb run--auto-servernum--server args=“-screen 0 640x480x24”--错误文件=/dev/stdout/opt/myExecutable
打印的命令是正确的
我还尝试了使用“-server args=”-screen 0 640x480x24'
(倒置的“
和”
,这导致了相同的结果(无法识别的选项:“-screen
)
在
子流程中运行的
更改了--server args=“-screen 0 640x480x24”
?正确的语法是:
args = [
'xvfb-run',
'--auto-servernum',
'--server-args=-screen 0 640x480x24',
'--error-file=/dev/stdout',
'/opt/myExecutable'
]
try:
from pipes import quote # Python 2
except ImportError:
from shlex import quote # Python 3
command_str = ' '.join(quote(s) for s in args)
print(f'Command: {command_str}')
subprocess.run(args) # or subprocess.run(command_str, shell=True)
请注意,这里根本没有文字引号——唯一的引号是Python语法。在bash中,未转义引号是语法,而不是数据,即使它们存在于字符串中。只是不要将命令合并到字符串中,然后不要将引号放在原来的位置,以保护字符串不受shell的影响
args = ['xvfb-run', '--auto-servernum','--server-args=-screen 0 640x480x24', '--error-file=/dev/stdout', '/opt/myExecutable']
print(f'Command: {args}')
subprocess.run(args)
下面是一种简单的方法,可以告诉您传递给
subprocess.run
的命令应该是什么样子。在shell(不是Python,一个常规shell)中,在要运行的命令之前插入Python-c“import sys;print(sys.argv[1:])”
:
19:59 ~ $ python -c 'import sys; print(sys.argv[1:])' xvfb-run --auto-servernum --server-args="-screen 0 640x480x24" --error-file=/dev/stdout /opt/myExecutable
['xvfb-run', '--auto-servernum', '--server-args=-screen 0 640x480x24', '--error-file=/dev/stdout', '/opt/myExecutable']
结果列表正是您应该传递给
子流程的内容。运行。在这里,我们可以看到shell将输入中的--server args=“-screen 0 640x480x24”
转换为一个没有引号的单参数。--server args=“-screen 0 640x480x24”
在bash中完全等同于“--服务器参数=-屏幕0 640x480x24"
。引号是按字符逐个计算的bash语法,而不是传递给xvfb run
的数据,因此不应该在数据中添加任何文字引号。OP继续将参数合并到单个字符串中,因此它们毕竟需要一些引号。但当然,更好的解决方案是保留参数作为列表。为了向用户打印,它们正在合并为字符串。最好使用shlex.quote()
对于该作业,生成与shell所需格式相同的内容。@tripleee我合并到一个数组中,以查看要运行的命令。我错过了subprocess.run
引用我的参数的部分,因为其中有一个空格。@Nepoxx,…也就是说,当您运行xvfb run--server args时=“-screen0640x480x24”
在bash中,它成为指向C字符串的指针数组,也可以描述为char**{“xvfb run”,“--server args=-screen0640x480x24”,NULL}
--这些字符串中的任何地方都没有引号;当shell认为引号意味着640x480x24
应该与--server args=
@Nepoxx在同一个参数中时,这些引号被shell使用和删除了,“任何必需的转义”都可能导致在某些平台上(即所有非Windows系统)实际上不需要转义。有关基本操作系统调用集的手册,请参阅man2execve
。