【问题标题】:Python subprocess to Bash: curly bracesBash 的 Python 子进程:花括号
【发布时间】:2012-01-27 14:44:20
【问题描述】:

我有以下 Python 行:

import subprocess
subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0]

不幸的是,bash 完全忽略了 --exclude=*{.git,.svn}* 标志。

我已将问题范围缩小到花括号。 --exclude=*.git* 将通过python的popen工作,但是在引入花括号的那一刻,我很无助。有什么建议吗?

注意:我尝试使用 Python 的 command 库运行该命令,它会产生完全相同的输出 -- 以及完全相同的被忽略 --exclude 标志。

【问题讨论】:

    标签: python bash popen


    【解决方案1】:

    我猜可能是shell转义?

    最好自己拆分参数,完全避免使用 shell?

    import subprocess
    subprocess.Popen(["egrep","-r","--exclude=*{.git,.svn}*","text","~/directory"], stdout=subprocess.PIPE).communicate()[0]
    

    注意:您可能需要扩展 ~,我不确定。

    或者如果 bash 应该扩展大括号,那么你可以在 python 中进行:

    excludes = ['.git','.svn']
    command = ['egrep','-r']
    for e in excludes:
        command.append('--exclude=*%s*'%e)
    command += ["text","~/directory"]
    subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
    

    【讨论】:

      【解决方案2】:

      当您传递 shell=True 时,python 将命令转换为 /bin/sh -c <command>(如 here 所述)。 /bin/sh 显然不支持花括号扩展。您可以尝试以下方法:

      import subprocess
      subprocess.Popen(["/bin/bash", "-c", "egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory"], stdout=subprocess.PIPE).communicate()[0]
      

      【讨论】:

      • 这和拆分参数以避免 shell 效果很好!
      【解决方案3】:

      您需要引用该表达式以防止 bash 在您启动它时根据您当前的工作目录对其进行评估。假设您正在寻找“文本”(带有引号),您的搜索词也存在错误。您的转义将引号放入 Python 字符串中,但需要再次完成才能让 shell 看到它们。

      ... --exclude='*{.git,.svn}*' \\\"text\\\" ...

      【讨论】:

        【解决方案4】:

        从 Python Popen 的角度来看,只要您将输出捕获到 Python 变量中,您编写的内容就可以工作:

        import subprocess
        myOutput = subprocess.Popen("egrep -r --exclude=*{.git,.svn}* \"text\" ~/directory", stdout=subprocess.PIPE, shell=True).communicate()[0]
        print "Output: ", myOutput
        

        我已经在终端中使用 Bash 作为默认 Shell 命令进行了测试,效果很好。

        请注意,“grep -E”应优先于“egrep”,后者现已弃用。

        您当然知道 \ 也是 Bash 的转义字符,不是吗?我的意思是,'*' 和花括号被 Bash 消耗,因此不会移交给 grep。因此,您应该避开它们。

        grep -Er --exclude=\*\{.git,.svn\}\* \"text\" ~/directory
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-31
          • 2019-01-26
          • 1970-01-01
          • 2023-03-26
          • 1970-01-01
          • 2021-11-16
          • 2021-07-04
          • 1970-01-01
          相关资源
          最近更新 更多