【问题标题】:Variables in subprocess.call command not being recognized on command line at runtime, files specifically运行时命令行无法识别 subprocess.call 命令中的变量,特别是文件
【发布时间】:2018-02-01 18:54:49
【问题描述】:

我正在尝试通过 subprocess.call() 传递以下命令

command = ['htseq-count', '-t', 'miRNA', '-i', 'Name', f, annot_file, out_file]

在运行时,我收到 htseq-count 至少需要 2 个参数的通知,这意味着它无法识别命令中有输入文件。

在运行时打印命令会得到以下结果:

['htseq-count', '-t', 'miRNA', '-i', 'Name', 'KDRD1XX_ACAGTG_L001_R1_001_trimmedaligned.sam', 'hsa.gff3', 'KDRD1XX.htseq.sam']

哪个是正确的文件输入。

插入打印出来的命令(当然没有逗号和引号)工作正常,所以没有问题。

在使用 subprocess.call() 之前使用变量列表没有任何问题,因此我们将不胜感激!

完整代码:

import sys
import subprocess
import os

annot_file='hsa.gff3'
dirs= os.listdir('.')

for f in dirs:
    if f.endswith("_trimmedaligned.sam"):

        of=f.split('_')
        outfile='>'+of[0]+'.htseq.sam'
        command=['htseq-count','-t','miRNA','-i','Name',f,annot_file, out_file] 
        #print(command)
        subprocess.call(command)

【问题讨论】:

    标签: python linux subprocess


    【解决方案1】:

    > 是 shell 语法。这是文件的标准输出redirection。这意味着您需要使用 subprocess.call(command, shell=True) 在 shell 中运行命令

    但是因为这需要仔细引用所有参数以防止shell command injection,我建议运行命令并保存 Python 的输出:

    for f in dirs:
        if not f.endswith("_trimmedaligned.sam"):
            continue
    
        of=f.split('_')
        outfile=of[0]+'.htseq.sam'
        command = [
            'htseq-count',
            '-t',
            'miRNA',
            '-i',
            'Name',
            f,
            annot_file,
        ]
    
        process = subprocess.Popen(command,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
    
        stdout, stderr = process.communicate()
    
        # Don't miss to check the exit status
        if process.returncode != 0:
            print("Ooops! Something went wrong!")
    
        # Write output file
        with open(out_file, 'wb') as fd:
            fd.write(stdout)
    

    PS:上面的例子适用于小输出文件。它缓冲内存中的所有输出。如果输出文件将达到合理的大小,您可以使用poll() 流式传输命令的输出,如下所述:https://stackoverflow.com/a/2716032/171318

    【讨论】:

    • 谢谢!做到了。奇怪的是,我之前尝试过,当一个 'grep' 命令失败但无济于事时,我什至没有想过要尝试它。
    • 很高兴它有帮助。请参阅我更新的答案。我建议在这种情况下使用Popen,因为您需要的唯一 shell 功能是将输出写入文件,这可以使用 Python 轻松完成。我假设输出不大,只有几 kb,对吗?
    • 它不是那么大,但我需要它作为程序生成的特别对齐的输出文件,而不仅仅是在 linux 中逐行生成的 line stdout,这就是为什么文件名前面的 > 是htseq-count 的可接受参数。感谢您为我省去一些麻烦!
    • 好吧,那没什么大不了的。
    • 所以,我认为它正在工作,但现在它的行为就像它只接收 'htseq-count' 而没有其他任何东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 2012-01-27
    • 2017-07-20
    • 2021-08-21
    • 1970-01-01
    相关资源
    最近更新 更多