산출

산출

exit오류로 호출시 스크립트가 종료되지 않습니다..

산출

Error: Could not resolve localhost
after exit

스크립트

#!/bin/sh

resolve_ip (){
    if [ -z "$1" ]; then
        host="localhost"
        ip=$(dig +short myip.opendns.com @resolver1.opendns.com)
    else
        host="$1"
        ip=$(dig +short $1)
    fi

    if [ -z "$ip" ]; then
        error "Could not resolve $host"
    fi

    echo "$ip"
}

error (){
    (>&2 echo "Error: $1")
    exit 1
}

master_host='google.com'

if [ "$(resolve_ip)" = "$(resolve_ip $master_host)" ]; then
    error "some error"
fi

echo "after exit"
exit

답변1

exit현재 쉘 프로세스를 종료합니다.

에서는 서브쉘 프로세스에서 실행 중입니다 $(resolve_ip).resolve_ip

넌 할 수있어:

my_ip=$(resolve_ip) || exit
master_ip=$(resolve_ip "$hostname") || exit
if [ "$my_ip" = "$master_ip" ]; ...

서브쉘이 0이 아닌 종료 상태로 종료되면 메인 쉘이 종료됩니다(서브쉘과 동일한 종료 코드로).

또한 resolve_ip하위 쉘 환경에서 실행 중이므로 하위 쉘이 반환된 후에는 $ip및 변수가 더 이상 존재하지 않습니다.$host

(...)또한 in은 (>&2 echo "Error: $1")서브쉘도 시작한다는 점에 유의하세요 . stderr이 손상된 파이프인 경우를 다루고 오류 메시지를 작성하면 SIGPIPE가 echo내장 프로세스 와 마찬가지로 기본 셸 프로세스로 전달되는 경우를 제외하고는 여기서는 실제로 필요하지 않습니다.

여기서는 stdout을 통해 출력을 반환하는 대신 사용자 제공 변수에 저장하여 반환할 수 있습니다.

resolve_ip (){ # args: ip_var [host]
    if [ "$#" -eq 1 ]; then
        host=localhost
        eval "$1="'$(dig +short myip.opendns.com @resolver1.opendns.com)'
    else
        host=$2
        eval "$1="'$(dig +short "$2")'
    fi

    if eval '[ -z "${'"$1"'}" ]'; then
        error "Could not resolve $host"
    fi
}

# ...

resolve_ip my_ip
resolve_ip master_ip "$hostname"

if [ "$my_ip" = "$master_ip" ]; ...

엄밀히 말하면 서브쉘 환경은 서브프로세스를 통해 구현될 필요가 없고 일부 쉘은 ksh93그렇게 최적화되지 않은 채 여전히 exit메인 쉘이 아닌 서브쉘만 종료한다. 그러나 하위 쉘 환경을 포함하지 않으므로 기본 쉘을 종료하는 양식 또는 명령 대체 ksh93가 있습니다 .${ ...; }exit

관련 정보