如何防止子进程在某些参数之间添加空格?

2 投票
2 回答
1275 浏览
提问于 2025-04-17 19:54

我想在Linux上用Python和它的 subprocess 模块执行一些Mysql命令。

不使用Python,在命令行中,我的命令是:

mysql --database=mydb --host=localhost --port=3306 --password=  --execute="select * from mytable" --batch

使用Python时,我有:

cmd = ['mysql']
cmd.extend(['--database=', self._database])
cmd.extend(['--password=', self._password])
cmd.extend(['--execute=', query])

(...)

p = subprocess.Popen(cmd, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
out, err = p.communicate()
errcode = p.returncode

不幸的是,这个方法不行(mysql只会打印用法说明),我 觉得,subprocess生成的输出是这样的 (' '.join(cmd)):

mysql --database= mydb --host= localhost --port= 3306 --password=  --execute= "select * from mytable" --batch

也就是说,每个参数之间会加上空格,把 = 和它的值分开。

当我把每个参数中的 = 去掉时 (cmd.extend(['--password', self._password])),就能正常工作,除了当某个参数是空的(所以,我会检查每个参数是否为空,如果是,就去掉它)。

最后,我找到了一种解决办法,通过检查空参数,但为了将来参考,有没有什么关于subprocess的技巧或用法我不知道,以处理这种 parameter= 的情况?总得有些地方是必须使用 = 的,我尽量避免使用 Shell=True

2 个回答

1

你在传递每个包含=符号的参数时,把它们当成两个不同的参数来处理。这样做是不对的,因为它们其实不是两个分开的参数。

cmd.append('--database=' + self._database)
cmd.append('--password='+ self._password)
cmd.append('--execute=' + query)

(大卫建议用[]一次性定义整个列表,而不是重复使用appendextend,这样写风格更好。)

6

把这个改成

cmd = [
    'mysql',
    '--database=%s' % self._database,
    '--password=%s' % self._password,
    '--execute=%s' % query
]

(...)

p = subprocess.Popen(cmd, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
out, err = p.communicate()
errcode = p.returncode

这样参数列表里就包含了开关和它们各自的参数

撰写回答