向 shell 脚本添加重试

Adding retry to shell script

提问人:PesKchan 提问时间:9/24/2023 最后编辑:PesKchan 更新时间:9/25/2023 访问量:61

问:

我的目标是增加此 fastq 验证的重试次数,该验证有时会因网络问题而失败,尽管有给定 NCBI SRA id 的数据,但它失败了。因此,在中止之前,我需要至少增加重试 5 次。

我该怎么做?

set -x
PS4='[\\d \\t] '

# Check parameter for error
check=0
# Print fastq-dump executable path
echo \$(which fastq-dump)

# Loop through all parameters to check validity
for file in \$@;
do
    cp \${file} .
    # Extract filename for sampleID
    file_basename=\$(basename \${file})
    id=\${file_basename%".id"}
    # Start validation
    echo "Checking \${id}..."
    # Download start of fastq
    fastq-dump $(get_ngc()) -X 1 -Z --split-spot \${id} > \${id}.test.fastq 2> \${id}.test.log
    # Get number of lines downloaded to valildate for error
    numLines=\$(cat \${id}.test.fastq | wc -l)
    if [ \$numLines -gt 0 ]; then
        echo "\${id} has data... OK"
    else
        echo "\${id} does not have data... ERROR"
        check=1
    fi
done
# Exit with error if some fastqs not accessible
if [ \$check -gt 0 ]; then
    echo "ERROR: One or more samples have inaccessible fastqs.. exiting"
    exit 1
fi
壳牌 FASTQ NCBI 通用工作流语言

评论

2赞 Benjamin W. 9/24/2023
这些反斜杠转义不是打破了一切吗?
1赞 shellter 9/24/2023
还要指出您调用哪个程序的位置“给定 ncbi sra id 的数据但(它)失败”,以及您如何知道(以及它在哪里发生)“由于网络问题而失败”。而且这里似乎有太多的代码;请阅读最小可重现示例,并阅读如何将糟糕的脚本变成好问题部分。(此建议适用于所有语言,而不仅仅是 bash)。此外,shellcheck.net 是找出语法问题的第一个地方。请务必将 #!/bin/bash(或其他)作为脚本的第一行。祝你好运。
1赞 shellter 9/24/2023
你知道 loop 和 bash/ksh 的算术求值吗?假设您当前的测试是对您提到的条件的令人满意的检查,那么在您的 cmd 应该工作之前插入一个带有适当测试的循环,您只需要在每个循环之前重置您。现在很忙。祝你好运。whileif (( errRetryCount++ > 5 )) ;then$numLines -gt 0whilecperrRetryCountwhile
0赞 PesKchan 9/24/2023
@shellter实际上,该脚本与CWL文件一起运行,其中我有一个调用并执行脚本的docker映像
0赞 PesKchan 9/24/2023
@BenjaminW。我从我得到的 CWL 文件中提取了脚本,所以我想它的工作方式是这样的

答:

2赞 tripleee 9/24/2023 #1

这是一个暂定的答案。希望至少它可以帮助您提出一个格式更合理的问题。

您在评论中提到反斜杠在“cwl 文件”中为您工作,但您还没有解释什么是“cwl 文件”。如果您指的是通用工作流语言,那么我们需要更多地了解脚本周围的 YAML 结构;当然有不需要反斜杠的 YAML 标量格式选项。

没有更多细节,我们只能说,对于“shell 脚本”,这些反斜杠正在破坏功能,因此我删除了它们。

目前还不清楚您究竟要捕获哪个错误条件。大概是这些错误的根源。如果它写得很合理,你应该能够简单地说fastq-dump

if fastq-dump --options arguments; then ...

但我坚持使用您计算输出行数的笨拙方法,因为我不熟悉此工具,并且您没有提供指向其文档的链接。

#!/bin/sh
# ^ explicitly name which shell you are using
# See also https://en.wikipedia.org/wiki/Shebang_(Unix)

set -x
PS4='[\\d \\t] '

check=0
# Avoid useless use of echo
# https://www.iki.fi/era/unix/award.html#echo
# Prefer POSIX "command -v" over nonstandard "which"
command -v fastq-dump

# Quote all file names
# https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable
for file in "$@"; do
    cp "$file" .
    # Basename knows how to trim extension
    id=$(basename "$file" .id)
    # Write diagnostics to stderr
    echo "$0: Checking $id..." >&2
    # Truncate log so we can append in a loop; see below
    : > "$id".test.log
    # Loop until success, or retries exhausted
    for retry in 1 2 3 4 5; do
        # Append rather than overwrite error log, in case we retry
        fastq-dump $(get_ngc()) -X 1 -Z --split-spot "$id" > "$id".test.fastq 2>> "$id".test.log
        # Avoid useless cat
        # https://stackoverflow.com/questions/11710552/useless-use-of-cat 
        numLines=$(wc -l < "$id".test.fastq)
        if [ $numLines -gt 0 ]; then
            echo "$0: $id has data... OK" >&2
            break
        else
            echo "$0: $id does not have data... ERROR" >&2
            case $retry in
             5) echo "$0: $id: aborting, after 5 attempts" >&2
                check=1;;
             *) # Sleep before retry
                sleep 5;;
            esac
        fi
    done
done
# Exit with error if some fastqs not accessible
if [ $check -gt 0 ]; then
    echo "$0: ERROR: One or more samples have inaccessible fastqs.. exiting" >&2
    exit 1
fi

这里的许多初学者错误都会被 https://shellcheck.net/ 检测到并经常修复;在询问这里之前,可能会通过此工具运行您的脚本,以避免分散回答者的注意力。显然,有时修复程序也会解决您想问的问题。

$(get_ngc())看起来仍然像语法错误,但我猜它是 CWL 的一部分......?

评论

0赞 PesKchan 9/24/2023
@triplee我已经在我的问题中添加了 CWL 文件供您查看
0赞 tripleee 9/25/2023
谢谢,虽然没有更多的上下文,我们仍然需要猜测你在说哪个CWL;这三个字母在谷歌上有很多点击率。我想如果你想让你的函数插值,你需要反斜杠所有其他美元符号。这是CWL项目中一个不幸的设计决定,但我们对此无能为力。
0赞 tripleee 9/25/2023
或者,可以将脚本保存到文件中,并将此参数作为命令行参数提供。
0赞 tripleee 9/25/2023
edwards.flinders.edu.au/fastq-dump 表明,也许根本没有写得称职。Quick Duck Duck Going 提出了一种名为fastq-dumpfasterq-dump