함수가 이미 실행된 경우 이를 우회하는 방법은 무엇입니까?

함수가 이미 실행된 경우 이를 우회하는 방법은 무엇입니까?

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함수가 작동하지 않는 상태로 전환됩니다.

한 가지 단점이 있습니다. 일반적으로 쉘 함수가 자체적으로 재정의될 것으로 기대하지 않습니다. 적어도 이 내용을 설명하는 댓글을 남겨야 합니다 # this function turns itself into no-op after first use. 플래그가 있는 메소드에는 그러한 주석이 없습니다(예:prereq_done바꾸다)은 플래그를 처리하는 데 필요한 명시적인 코드로 인해 더 읽기 쉽습니다.


*대부분 처음에 발생합니다. 그러나 원래 함수가 "함수 실행"으로 간주되지 않는 방식으로 일찍 종료되는 경우 이 시점 이후에 재정의해야 할 수도 있습니다. 마지막에는 함수의 종료 상태에 영향을 미친다는 점을 기억하세요.

관련 정보