下次只应运行失败的 bash 脚本

下次只应运行失败的 bash 脚本

我有一个主脚本,其中包含多个子脚本。一旦我运行主脚本,它将开始顺序执行所有子脚本。有些脚本会通过,有些可能会失败。当我第二次运行这个主脚本时,我只想运行失败的子脚本而不是成功的子脚本。任何帮助将不胜感激。

我的第二个问题是,有一个论点说“r”对于所有脚本都是通用的……而“d”是可选的。例如: mainscript.sh -r India -d 2021-05-21 但我的第一个子脚本没有 d 参数,因此每次运行都会失败。我如何忽略这个无效参数并运行脚本。

#!/bin/bash

recall() {
script1.sh $* ;
script2.sh $* ;
script3.sh $* ;
script4.sh $* ;
script5.sh $* 
exit
}
recall $*

答案1

确保脚本(或任何程序)只能运行一次的常用方法是在某个地方创建一个维护状态的标志。

出于本示例的目的,我们将用户主目录中是否存在一个文件作为标记:如果该文件存在,则应用程序已成功运行,并且不得再次运行。

#!/bin/bash
flag="$HOME/.my_script.flg"
{[ ! -f "$flag" ]] && my_script && touch "$flag"

在这里,我们测试文件是否存在$flag。如果它不存在,我们运行一个外部脚本my_script,并提供它以 success/0 状态退出,我们创建该$flag文件。请注意,存在竞争条件:如果您同时运行此控制脚本的两个实例,则可能会导致第一个脚本无法创建标志文件,直到第二个脚本已经开始运行相同的子脚本为止。我要去忽略这个问题前提是您的用户应该知道他们在做什么,如果他们不知道,那么您需要考虑确保只能同时运行脚本的单个实例。

这可以根据您的具体情况进行扩展:

#!/bin/bash
recall() {
    local script flag
    for script in script{1,2,3,4,5}.sh
    do
        flag="$HOME/.${script%.sh}.flg"
        [[ ! -f "$flag" ]] && "$script" "$@" && touch "$flag"
    done
    exit 0
}
recall "$@"

在这里,该$script变量用于迭代要执行的子脚本或函数的名称。我们假设每个都0成功返回,否则返回非零。

如果您希望整体退出状态在0成功时为成功,在任何失败时为非零,则需要稍微扩展脚本(我们返回失败的模块数量,无论运行的模块数量如何):

#!/bin/bash
recall() {
    local script flag error=0
    for script in script{1,2,3,4,5}.sh
    do
        flag="$HOME/.${script%.sh}.flg"
        if [[ ! -f "$flag" ]]
        then
            if "$script" "$@"
            then
                touch "$flag"
            else
                ((error++))
            fi
        fi
    done
    return $error
}
recall "$@"

不用说,删除适当的标志标记文件以允许重新运行相应的子脚本。

相关内容