【问题标题】:Subprocess - using several command line tools子进程 - 使用几个命令行工具
【发布时间】:2012-10-05 04:43:20
【问题描述】:

我是一个学习 python 和在命令行中工作的新手,例如管道。

我读过鼓励使用子进程而不是 os.system。我正在创建一个调用 shell 的脚本,但我无法使用子进程来完成它。不过使用 os.system 很简单:

os.system("cut -f1-4 " + temp1.name + "| uniq --count | sort -rn > " + temp2.name)

我已经成功地将 subprocess 用于其他命令,但不是那些将多个工具与“|”组合在一起的命令。阅读 subprocess python 文档令人困惑,对我没有帮助。我也尝试搜索其他问题,但找不到与我的问题类似的问题。这是我尝试过的(但失败了):

subprocess.call = (["cut", "-f1-4", temp1.name, "|",  "uniq", "--count", "|", "sort". "-rn"], stdout = open(temp2.name, 'w'))

我也试过用 sp.Popen 代替 sp.call,但失败了。谁能帮忙提供一些清晰的例子和解释? 谢谢!

【问题讨论】:

  • subprocess.call = (… - 你刚刚用一个元组替换了一个库函数。你为什么期望它起作用?你需要调用函数...
  • 对不起,我不确定你的意思。你能进一步解释一下吗?我通过调用列表中的项目成功使用了 subprocess.call,例如subprocess.call(["程序", 输入文件, 输出文件])

标签: python command-line subprocess pipe os.system


【解决方案1】:

如果你想使用管道,你应该添加shell=True

subprocess.check_output("cut -f1-4 " + temp1.name + "| uniq --count | sort -rn > " +    temp2.name, shell=True)

请注意,如果 temp1.nametemp2.name 来自不受信任的来源(例如来自用户在 Web 应用程序中提供的数据),则使用 shell=True 存在安全风险。

【讨论】:

  • 谢谢@hans!那行得通!但是我不清楚为什么要使用 sp.check_output ,因为我想读取输出而不仅仅是检查命令是否有效?这令人困惑。无论如何,安全风险很小,因为 temp1.name 和 temp2.​​name 文件是由脚本根据特定的用户输入生成的。
  • 抱歉增加了混乱。如果您只想检查返回值,您可以简单地使用call。习惯的力量让我输入check_output
  • 嗯,我发誓我之前尝试过,但它不适用于 sp.call。这就是为什么我将整行分成一个列表,因为这是 sp.call 接受的(根据我的理解)。无论如何,再次感谢!
  • 也许你第一次没有指定shell=True
  • 我尝试了太多无法记住的事情。我想我试过了,但是当我读到 sp.call 需要列表中的项目时,我将命令分解为列表项(例如有问题),这就是我一直在使用 sp.call 的方式。然后我添加了 shell=True 但它不起作用。但是再次感谢,我今天学到了一些新东西。 :)
【解决方案2】:

值得一看的是伟大的库python sh,它是一个成熟的 Python 子进程接口,允许您调用任何程序,就好像它是一个函数一样,更重要的是,它是令人愉悦的 Python 风格。

针对您在这种情况下的特定需求,它提供了一些“高级管道”功能,如下所示:

# the inner command executes first, then sends its data to the outer command
from sh import *
sort(uniq(cut("-f1-4", _in="temp1.name"), "--count"), "-rn", _out="temp2.name")

【讨论】:

  • 谢谢@chuchao333,我去看看。
猜你喜欢
  • 2017-02-06
  • 1970-01-01
  • 2013-07-18
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2015-03-04
相关资源
最近更新 更多