Não é uma boa idéia usar set -e
dentro de funções 1 , porque isso fará com que o shell de uma pessoa termine em erro.
Portanto, nas funções do shell, um lote do meu código se parece com isto:
[[ -e $file ]] || {
printf -- 'foo: %s does not exist\n' $file >&2
return -1
}
... que não é apenas volumoso, mas também ineficaz para além do primeiro quadro de funcstack
.
Seria ótimo se houvesse uma função error
que permitiria pelo menos condensar o código acima para algo como isto
[[ -e $file ]] || error -1 '%s does not exist' $file
Escrever uma função de erro para uso em scripts interpretados (em oposição a funções) não é muito difícil:
error () {
local exitstatus=$1
shift
{
printf -- '%s: ' "${funcstack[2]}"
printf -- "$@"
printf -- '\n'
} >&2
exit $exitstatus
}
... mas chamar essa função de outras funções é uma má ideia, pela mesma razão que set -e
dentro das funções é uma má idéia.
O que é necessário para implementar a função error
desejada é uma maneira de retornar o controle ao "nível superior" do shell invocador (limpando assim funcstack
, que pode ser arbitrariamente longo no momento em que error
é invocado). / p>
Existe uma maneira de fazer isso?
PS: Claro, eu tentei o caminho ingênuo para isso:
error () {
local exitstatus=$1
shift
{
printf -- '%s: ' "${funcstack[2]}"
printf -- "$@"
printf -- '\n'
} >&2
funcstack=()
}
... mas (sem surpresa), zsh
não terá nada disso:
error:10: read-only variable: funcstack
1 Neste post eu vou usar expressões como "de dentro de uma função" como abreviação para "de dentro de funções de shell destinadas a uso interativo ou de dentro de scripts destinados a serem originados" .
Tags zsh shell-script