出力

出力

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" ]; ...

サブシェルがゼロ以外の終了状態で終了すると、メインシェルは終了します(サブシェルと同じ終了コードで)。

また、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

関連情報