如果函数已经执行,如何绕过它?

如果函数已经执行,如何绕过它?

prereq()我有一个可能会被调用多次但实际上不应该被调用的函数被处决通过从菜单中选择其他选项,在脚本的同一运行线程上多次运行(菜单上的每个选项都将作为prereq()代码的一部分):

# Pre-requirements
prereq ()
{
        echo
        echo "########################## CHECKING PRE-REQUIREMENTS ##########################"
        echo "#                                                                             #"
        echo "Required packages: hdparm, fio, sysbench, iperf3 and sshpass"
        sleep 2
        echo
        for pack in hdparm fio sysbench iperf3 sshpass; do
                echo "Checking and if needed install '$pack'..."
                if ! rpm -qa | grep -qw "$pack"; then
                        yum install -y $pack > /dev/null
                else
                        echo "$pack is already installed, skipping..."
                        echo
                fi
        done
        echo "###############################################################################"
echo
}

该函数执行如下:

select opt in "${options[@]}"
do
        case $opt in
        "CPU Stress Test (local)")
                sleep 2
                prereq                ===>> HERE IS!
                cpu
                cleanup
                echo
                break
        ;;
        "Memory Stress Test (local)")
                sleep 2
                prereq                ===>> HERE IS!
                memory
                cleanup
                echo
                break
                .
                .
                .

prereq()即使从调用的菜单中选择其他选项,我也只需执行一次prereq(),因为每个函数都可以执行一次,并且脚本的目的已完成,并且可以退出。

我计划将一个变量作为prereq()标志,如果执行它,则每次prereq()在菜单中的任何选项上调用该标志时都会检查该标志。

此外,我感谢任何帮助!谢谢!

答案1

由于 shell 变量是全局的,除非您将它们声明为local函数内部(顺便说一句,这是一个平均陷阱),所以您可以简单地定义一个变量

prereq_done=0

在脚本顶部,然后修改prereq()函数以在开头检查它(如果已设置则退出),并在最后将其设置为 1:

prereq()
{
  if (( prereq_done == 1 )); then return; fi

  < your code here >

  prereq_done=1
}

答案2

让函数重新定义自己。将其放在函数体中的某处*:

prereq () { :; }

第一次执行prereq会将函数变成无操作。

有一个缺点。人们通常不期望 shell 函数被重新定义;更不用说被它自己重新定义了。您至少应该发表评论说明这​​一点# this function turns itself into no-op after first use。没有这样的评论,带有标志的方法(例如prereq_done多变的)由于处理该标志所需的显式代码而更具可读性。


*最有可能在开始时;但是,如果原始函数以某种不应该算作“函数已执行”的方式提前退出,那么您可能需要在此点之后重新定义。如果在最后,请记住它将影响函数的退出状态。

相关内容