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