【问题标题】:Unable to run shell commands with * using python subprocess module无法使用 python 子进程模块运行带有 * 的 shell 命令
【发布时间】:2016-03-16 04:30:51
【问题描述】:

我无法使用包含* 登录命令的python 子进程模块运行任何命令。 我用这种方式调用,

 subprocess.Popen(
            'cp /etc/varnida_sys/* /tmp/bucket/'.split(),
            stdout=subprocess.PIPE).communicate()[0]

为此,我得到了,

cp: cannot stat ‘/etc/varnida_sys/*’: No such file or directory

为什么会出现这个错误,/etc/varnida_sys/genders里面有一个文件

我的调查表明,使用像 * 这样的正则表达式需要一些特殊处理。我在所有包含 * 的命令中都遇到了一些错误。

PS。当我从远程主机通过 paramiko 运行相同的命令时,我没有收到错误。

【问题讨论】:

  • 添加了linux。它在 Linux 上不起作用(正如 eugene 所解释的那样),但在 Windows 上起作用(将 cp 替换为 copy 或使用 powershell -c cp ... 运行)。

标签: python linux shell subprocess


【解决方案1】:

* 只能被 shell 理解(将其扩展为文件列表),您需要将shell=True 传递给Popen()。另外,命令不需要拆分,可以使用字符串:

subprocess.Popen("cp /etc/varnida_sys/* /tmp/bucket/",
                 stdout=subprocess.PIPE, shell=True).communicate()[0]

正如@triplee 在下面建议的那样,最好为此任务使用一些方便的包装器,例如subprocess.call():

subprocess.call("cp /etc/varnida_sys/* /tmp/bucket/", shell=True)

【讨论】:

  • 但是,您想要更简单的subprocess.call()shell=True 的要求仍然成立。
  • @tripleee: 来自docs on subprocess.call(): 不要使用 stdout=PIPE 或 stderr=PIPE 这个函数。如果子进程生成足够的输出到管道以填满操作系统管道缓冲区,则子进程将阻塞,因为管道没有被读取。
  • 你期望什么输出?应该没有;或改用subprocess.check_output()。我的观点是Popen 对于琐碎的任务来说是不必要的复杂;这就是为什么有许多针对常见场景的便捷包装器。
猜你喜欢
  • 1970-01-01
  • 2011-10-30
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-23
相关资源
最近更新 更多