関数がすでに実行されている場合、それをバイパスする方法は何ですか?

関数がすでに実行されている場合、それをバイパスする方法は何ですか?

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

localシェル変数は関数内で宣言しない限りグローバル変数であるため、これは一種のトラップです。単に変数を定義できます。

prereq_done=0

スクリプトの上部でprereq()関数を変更して最初にそれを確認し(設定されている場合は終了)、最後に1に設定します。

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

  < your code here >

  prereq_done=1
}

答え2

関数が自分で上書きされるようにします。関数本体*のどこかに入れてください。

prereq () { :; }

最初の実行では、prereq関数が機能していない状態に切り替わります。

1つの欠点があります。通常、シェル関数はそれ自体をオーバーライドすることを期待していません。少なくともこの内容を説明するコメントを残す必要があります# this function turns itself into no-op after first use。フラグ付きのメソッドにはそのようなコメントはありません(例:prereq_done変える)は、フラグを処理するために必要な明示的なコードのためにより読みやすくなります。


*ほとんど最初に発生します。ただし、元の関数が「関数実行」と見なされないように早く終了した場合は、この時点以降にオーバーライドする必要があります。最後に、関数の終了状態に影響を与えることに注意してください。

関連情報