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

raf*_*ias 7 shell-script variable

我有一个函数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
}
Run Code Online (Sandbox Code Playgroud)

该函数执行如下:

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
                .
                .
                .
Run Code Online (Sandbox Code Playgroud)

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

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

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

Adm*_*Bee 18

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

prereq_done=0
Run Code Online (Sandbox Code Playgroud)

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

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

  < your code here >

  prereq_done=1
}
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 13

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

prereq () { :; }
Run Code Online (Sandbox Code Playgroud)

第一次执行prereq将把函数变成空操作。

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


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