【问题标题】:How to escape arguments for the command line in python?如何在python中转义命令行的参数?
【发布时间】:2019-07-26 12:10:18
【问题描述】:

我正在编写一个需要使用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 的解决方案将不胜感激。

【问题讨论】:

  • 你使用列表,而不是字符串。 subprocess.run(["ls", "-l"])

标签: python shell shlex


【解决方案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'

【讨论】:

  • 我不能。我使用的命令在我的PATH 上,所以我需要使用shell=True,根据docs,建议在这种情况下传递字符串而不是序列
  • 使用绝对路径如subprocess.run(["C:/path/to/binary", "arg1", "arg2" , f])
  • 但我不想硬编码路径。在不同的计算机或平台上可能不一样。
  • 一种可能的解决方案是使用where 命令来查找二进制文件的位置(where 在最新版本的 Windows 上可用)例如 c:\>where ping 返回 C:\Windows\System32\PING.EXE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多