在 bash 脚本中创建步骤

Posted

技术标签:

【中文标题】在 bash 脚本中创建步骤【英文标题】:Creating steps in bash script 【发布时间】:2019-05-01 23:10:21 【问题描述】:

首先,我对 shell 脚本比较陌生。我想知道是否有人可以帮助我在 bash 脚本中创建“步骤”。例如,我想运行一次分析,然后让脚本使用第一次分析中生成的输出文件进行下一次分析。

例如,下面的脚本会生成输出文件“filt_C2”:

./sortmerna --ref ./rRNA_databases/silva-arc-23s-id98.fasta,./index/silva-arc-23s-id98.db:./rRNA_databases/silva-bac-23s-id98.fasta,./index/silva-bac-23s-id98.db:./rRNA_databases/silva-euk-18s-id95.fasta,./index/silva-euk-18s-id95.db:./rRNA_databases/silva-euk-28s-id98.fasta,./index/silva-euk-28s-id98.db:./rRNA_databases/rfam-5s-database-id98.fasta,./index/rfam-5s-database-id98.db:./rRNA_databases/rfam-5.8s-database-id98.fasta,./index/rfam-5.8s.db --reads ~/path/to/file/C2.fastq --aligned ~/path/to/file/rrna_C2 --num_alignments 1 --other **~/path/to/file/filt_C2** --fastx --log -a 8 -m 64000

此步骤完成后,我想运行另一个步骤,该步骤将使用生成的输出文件“filt_C2”。我一直在为每个步骤创建多个 bash 脚本;但是,如果我可以在一个 bash 文件中执行每一步,效率会更高。那么,有没有办法制作一个脚本来完成第 1 步,然后使用第 1 步中生成的文件转到第 2 步?任何提示将非常感谢。谢谢!

【问题讨论】:

【参考方案1】:

欢迎使用 bash 脚本!

这里有一些提示:

    您可以在一个 bash 脚本文件中包含任意多行。 您可以从您的 shell 脚本中调用其他 bash 脚本(或任何其他可执行程序),正如 Frank 在他的回答中提到的那样。 您可以使用变量使您的脚本更通用,例如,如果您想将结果命名为“C3”而不是“C2”。 (以下未显示) 如果您的脚本变得更复杂,您可以使用 bash 函数,例如见https://ryanstutorials.net/bash-scripting-tutorial/bash-functions.php 我建议将 sortmerna 放在环境 PATH 变量中的目录中,并将多个 ~/path/to/file 替换为另一个变量(例如 WORKDIR)以保持一致性和灵活性。

例如,假设您将脚本命名为 print_analysis.sh

#!/bin/bash

# print_analysis.sh
# Written by Nikki E. Andrzejczyk, November 2018

# Set variables
WORKDIR=~/path/to/file

# Stage 1: Generate filt_C2 using SortMeRNA
./sortmerna --ref ./rRNA_databases/silva-arc-23s-id98.fasta,./index/silva-arc-23s-id98.db:./rRNA_databases/silva-bac-23s-id98.fasta,./index/silva-bac-23s-id98.db:./rRNA_databases/silva-euk-18s-id95.fasta,./index/silva-euk-18s-id95.db:./rRNA_databases/silva-euk-28s-id98.fasta,./index/silva-euk-28s-id98.db:./rRNA_databases/rfam-5s-database-id98.fasta,./index/rfam-5s-database-id98.db:./rRNA_databases/rfam-5.8s-database-id98.fasta,./index/rfam-5.8s.db \
            --reads "$WORKDIR/C2.fastq" \
            --aligned "$WORKDIR/rrna_C2" \
            --num_alignments 1 \
            --other "$WORKDIR/filt_C2" \
            --fastx --log -a 8 -m 64000

# Stage 2: Process filt_C2 to generate result_C2
./stage2 "$WORKDIR/filt_C2" > "$WORKDIR/result_C2.txt"

# Stage 3: Print the result in result_C2
less "$WORKDIR/result_C2.txt"

请注意我如何使用尾部反斜杠 \,以便我可以将长的 sortmerna 命令拆分为多个较短的行,以及将 # 用于人类可读的 cmets。

上面提到的还有改进的空间,但在这个快速示例中没有实现,但希望这个快速示例向您展示如何扩展您的 bash 脚本并使其一次执行多个步骤。

Bash 实际上是一种非常强大的脚本和编程语言。要了解更多信息,您可能需要从以下 Bash 教程开始:

https://ryanstutorials.net/bash-scripting-tutorial/ http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html

希望这会有所帮助!如果您还有其他问题,或者我误解了您的问题,请随时提出!

干杯,

安东尼

【讨论】:

我要添加一个警告:如果脚本中的任何命令(“步骤”)失败,它将盲目地继续执行其余的命令,即使这没有意义。 (第一次分析失败?让我们继续对其不存在/空的输出文件进行第二次分析!)如果在脚本开头添加set -e(或将第一行更改为“#!/bin/bash -e”),它'如果任何命令失败,则退出(有一些令人困惑的异常,但这是一个高级主题...)这通常更安全,尤其是在您刚开始时。 哦,还有一点需要注意:shell 脚本很容易上手,但也有一些很容易掉入的陷阱。 shellcheck.net 擅长发现常见错误,因此我建议通过它运行您的脚本作为健全性检查。 (说到这一点,我将对这个答案进行小幅编辑,以修复一个真正常见的错误——变量引用周围没有双引号。) 感谢您的有用建议!这正是我一直在寻找的。另外..当我在这里时,我不妨问问。假设我有多个要分析的文件——所以除了 C2.fastq(从上面)之外,我还有 C1.fastq。我知道我可以指定我想告诉脚本使用 C*.fastq 来使用这两者。但是,如何从上面更改输出文件名 filt_C2.fastq 以反映初始输入文件的名称?我知道这有点离题,但如果你能指出我正确的方向,那就太好了。

以上是关于在 bash 脚本中创建步骤的主要内容,如果未能解决你的问题,请参考以下文章

bash 脚本,在目录中创建所有文件的数组

在bash中创建一个循环脚本,其中2个变量递增,第二个变量根据第一个变量[重复]

在centos中创建nginx启动脚本

如何在 Docker Postgres 的脚本中创建用户/数据库

在 bash 3 中创建关联数组

如何在 bash 中制作聊天脚本?