【问题标题】:Running bash command with redirection in python在python中运行带有重定向的bash命令
【发布时间】:2019-07-29 08:31:00
【问题描述】:

我想使用从 bash 函数返回值重定向到例如grep,然后从 python 调用它。

即使我在子进程中使用shell=True,这似乎也不起作用。

适用于 bash 的示例:

grep foo <(echo "fooline")

在 python 3.7.3、Ubuntu 19.04 中给出错误 /bin/sh: 1: Syntax error: "(" unexpected 的示例:

#!/usr/bin/env python3
import subprocess
subprocess.call('grep foo <(echo "fooline")', shell=True)

根据these 之类的答案,重定向应该与 shell=True 一起使用(它适用于重定向实际文件,但不是返回值)。

编辑: 添加了shebang和python版本。

【问题讨论】:

  • 最好为此类所有不一致的问题提供良好的文档,以便人们能够从 bash 脚本迁移到 python 脚本,而不会出现太多不可预测的行为。
  • echo "fooline" | grep foo?
  • 你的例子对我有用。你运行的 python 版本是什么?
  • 似乎你缺少 python shebang 你的 python 脚本被解释为 shell
  • 我正在运行 python 3.7.3 @PiotrKamoda

标签: python bash subprocess


【解决方案1】:

您观察到的不一致是因为shell=True 给您一个sh shell,而不是bash

以下内容在bash 中有效,但在sh 中无效。

grep foo <(echo "fooline")

示例输出:

sh-3.2$ grep foo <(echo "fooline")
sh: syntax error near unexpected token `('

如果您使用有效的sh 表达式,您的方法将有效。或者,您可以指定与executable='/bin/bash' 一起使用的shell。你也可以使用类似的东西:

subprocess.Popen(['/bin/bash', '-c', cmd])

【讨论】:

    【解决方案2】:

    该错误是shell错误,与python无关。 sh 扼杀了 Python 语法的括号。

    /bin/sh: 1: 语法错误:“(”意外

    让我们添加一个shebang(参考:Should I put #! (shebang) in Python scripts, and what form should it take?

    并且停止使用shell=True 等等。使用带有参数的真实管道和命令行(注意:这已经在 windows 上使用原生 grep 命令进行了测试和工作,所以现在这是可移植的)

    #!/usr/bin/env python3
    import subprocess
    
    p = subprocess.Popen(['grep','foo'],stdin = subprocess.PIPE)
    p.stdin.write(b"fooline\n")
    p.stdin.close()
    p.wait()
    

    【讨论】:

    • 使用 python 管道的问题在于它不允许我们将经过良好测试的 bash 代码放入 python 脚本中。该解决方案要求我们将所有内容重构为 python 样式。关于如何在使用shell=True 时执行此操作的任何想法?
    • 添加shebang没有帮助
    • 好吧,我不确定你真正需要什么。如果你使用 python 来测试 bash 代码,那么你不能使用我的解决方案。当你想让你的代码更少时考虑一下pythonic,并且......也许是时候完全放弃 bash 并切换到 python 来编写脚本了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2011-08-29
    • 2021-08-28
    • 2011-07-24
    相关资源
    最近更新 更多