exit
sai do processo atual do shell¹.
Em $(resolve_ip)
, resolve_ip
está sendo executado em um processo de subshell.
Você pode fazer:
my_ip=$(resolve_ip) || exit
master_ip=$(resolve_ip "$hostname") || exit
if [ "$my_ip" = "$master_ip" ]; ...
Para o shell principal sair (com o mesmo código de saída que o subshell) quando a subshell sair com um status de saída diferente de zero.
Além disso, como resolve_ip
é executado em um ambiente subshell, as variáveis $ip
e $host
não sobreviverão depois que a subshell retornar.
Observe também que o (...)
in (>&2 echo "Error: $1")
também inicia uma subshell. Não é realmente necessário aqui, a menos que você queira cobrir o caso em que stderr é um pipe quebrado e gravar a mensagem de erro causaria uma entrega SIGPIPE para o processo principal do shell, pois echo
está embutido.
Aqui, em vez de retornar a saída ao stdout, você poderia retorná-lo armazenando-o em variáveis fornecidas pelo usuário:
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" ]; ...
¹ Estritamente ambientes subshell não precisam ser implementados com processos filho, e alguns shells como ksh93
não são como uma otimização, mas ainda assim exit
só sai da subshell, não o principal Concha. ksh93
no entanto tem uma ${ ...; }
forma ou substituição de comando que não envolve um ambiente subshell, então exit
em que sairia do shell principal.