首页 > 解决方案 > 在 python 代码中运行 bash for 循环时出错

问题描述

我想使用以下命令for在我的 python 代码中运行 bash 循环,但它不起作用 ant 给出了错误:

os.system("for f in *.sam ; do samtools flagstat $f > ${f/.sam/.stat};done ")

错误是

文件 "", 第 1 行 os.system("for f in *.sam ; do samtools flagstat $f > ${f/.sam/.stat};done ") ^

如何for在 python 代码中使用 bash 循环?

标签: pythonbash

解决方案


您正在尝试在代码中使用 Bash 功能 ( ${variable/pattern/substitution}) 。sh您可以使用subprocess.runwithexecutable='/bin/bash'但实际上绝对没有理由在 shell 中运行循环。

import glob
import subprocess

for file in glob.glob('*.sam'):
    with open(file.replace('.sam', '.stat'), 'w') as output:
        subprocess.run(['samtools', 'flagstat', file],
            stdout=output, check=True)

check=True假设返回一个有用的samtools退出代码,并且您想知道它是否失败。

一般来说,您应该在 a 中运行尽可能少的代码,subprocess因为它基本上发生在您的控制之外。你自己用 Python 编写的部分(或者更好的是import来自维护良好的库)可以由你的 Python 代码正确管理,而与外部进程的通信必然受到限制。

也许另请参阅从 Python 运行 Bash 命令,了解为什么要避免os.system以及 sh 和 bash 的确切含义check=True以及区别子进程中 'shell=True' 的实际含义解释了为什么要尽可能避免调用 shell。

为了完整起见,这里是一个语法正确、sh兼容的for循环:

for f in *.sam; do
    samtools flagstat "$f" >"${f%.sam}.stat"
done

注意引号。

(如果你绝对想要一个单行,你可以用done分号替换之前的换行符。)


推荐阅读