如何在python中为命令行转义参数?

时间:2019-07-26 12:10:18

标签: python shell shlex

我正在编写一个脚本,该脚本需要使用subprocess模块来调用外部命令。问题是我需要将用户提供的文件传递给命令,因此它看起来类似于:

p = subprocess.run("command arg1 arg2 {userfile}".format(userfile=f),
                   capture_output=True, text=True, shell=True)

我必须使用shell=True运行命令以使其起作用,这就是为什么我将命令作为字符串而不是列表传递的原因。

问题是某人可能会传递一个名为somefile && rm -rf ~的文件,这是一个奇怪的原因(至少在Windows上不知道mac / linux),因此该文件名无效,然后出现了不好的情况发生。

因此,我需要先将用户输入转义给shell,然后再转义。我想为此使用内置的shlex.quote函数,因此在上面的示例中,我得到:'somefile && rm -rf ~',命令变为:command arg1 arg2 'somefile && rm -rf ~cmd',该命令应该在unix系统上工作。问题是这种转义在Windows上无法通过命令提示符进行,因此我的脚本在Windows计算机上失败。

是否有一个内置的或第三方的函数/库可以针对所有平台或至少对于Windows正确地转义命令行参数(因为shlex.quote在Unix上有效)?

我正在Windows上进行开发,因此我需要此脚本在此平台上工作,并且我认为"{userfile}"之类的东西还不够好。

任何针对python 3的解决方案都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

将列表传递给子流程,例如

p = subprocess.run(["command", "arg1", "arg2" , f],
                   capture_output=True, text=True)

有关Windows的更新

使用到预期二进制文件的绝对路径通常是最好的方法,将命令更改为:

p = subprocess.run(["C:\\path\\to\\binary.exe", "arg1", "arg2" , f],
                   capture_output=True, text=True)

如果绝对路径未知,则可以使用which查找二进制文件(在Windows的最新版本中,我在Windows 7上进行了测试)。

>>> p = subprocess.run(["which", "python"], stdout=subprocess.PIPE)
>>> python_binary = p.stdout.strip().decode()  # Convert back to str
>>> python_binary
'C:\\Program Files\\Python36\\python.exe'