【问题标题】:Incorporate complex bash command into python将复杂的 bash 命令合并到 python 中
【发布时间】:2014-04-08 02:51:08
【问题描述】:

我需要从 python 脚本调用 bash 并将结果存储在变量中(输出为一个数字)。

我需要

output = subprocess.call('command', shell=True)

command 替换为我的 bash 单行代码的输出,如下所示:

cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'

我知道简单的命令可以正常工作:

    output = subprocess.check_output("echo 122;", shell=True)

我的问题是,我需要 bash 单行而不是 122。如果我不需要重新格式化它并且可以按原样使用它,那将是完美的

这是我的尝试:

    output = subprocess.check_output("cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
    ", shell=True)

      File "script.py", line 9
        output = subprocess.check_output("cat file.sam | grep -v "@" | grep "gi|519666810|ref|NM_001278619.1|"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
                                                                  ^
    SyntaxError: invalid syntax

尝试二:

    output = subprocess.check_output("cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
", shell=True)

  File "script.py", line 9

    output = subprocess.check_output("cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'
                                                                                                                                                                                                                    ^
SyntaxError: EOL while scanning string literal

【问题讨论】:

  • 我不明白你的问题是什么。它适用于echo 122 吗?当你用你的实际命令替换它时会发生什么?
  • 您需要将 bash 命令管道分解为子进程的各个命令,然后使用子进程创建管道。但说真的,为什么不在 python 中这样做而不是搞乱 bash?
  • @Blorgbeard 我编辑了我的问题以使其更清楚,谢谢
  • 您在最后一次尝试中错过了结束 ")

标签: python bash


【解决方案1】:

感谢您的帮助!最后,这行得通:

command = "cat file.sam | grep -v \"@\" | grep \"gi|519666810|ref|NM_001278619.1|\"  | perl -lane '$l = 0; $F[5] =~ s/(\d+)[MX=DN]/$l+=$1/eg; print $l' | awk '{ sum+=$1} END {print sum}'";
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
#Launch the shell command:
output = process.communicate()[0];

【讨论】:

  • 我意识到这段代码很简洁,但是使用带有shell=True 的子进程是不好的做法——它非常等同于在 bash 中使用eval,具有所有相同的随之而来的安全性和正确性问题.正确的做法虽然可能很长,但在单独的 Popen 对象中为每个管道元素指定 argv。
猜你喜欢
  • 2020-01-10
  • 2019-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-04
  • 2023-01-20
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多