Como faço para que um source
script d retorne automaticamente se algum comando dentro dele falhar?
Suponha que eu tenha um script que sai automaticamente em caso de falha via set -e
, por exemplo
#!/bin/bash
# foo.env
set -e # auto-exit on any command failure
echo "hi"
grep 123 456 # this command will fail (I don't have a file named "456")
echo "should not reach here"
Se eu executar o comando normalmente, ele sairá automaticamente no grep
comando com falha:
box1% ./foo.env
hi
grep: 456: No such file or directory
No entanto, se eu usar source
o script, ele sairá do meu shell atual, e não apenas do script que está sendo originado:
box1% ssh box2
box2% source ./foo.env
hi
grep: 456: No such file or directory
Connection to box2 closed.
box1%
Se eu remover o set -e
,
#!/bin/bash
# foo2.env
echo "hi"
grep 123 456 # this command will fail (I don't have a file named "456")
echo "should not reach here"
então ele não sai nem retorna automaticamente o source
script d:
box1% ssh box2
box2% source ./foo2.env
hi
grep: 456: No such file or directory
should not reach here
box2%
A única solução que encontrei até agora é adicionar uma return
expressão a cada linha de código do script, por exemplo
box1% cat foo3.env
#!/bin/bash
# foo3.env - works, but is cumbersome
echo "hi" || return
grep 123 456 || return
echo "should not reach here" || return
box1% source foo3.env
hi
grep: 456: No such file or directory
box1%
Existe outra maneira para source
scripts d, semelhante a como set -e
funciona para source
scripts não-d?
Responder1
Quando você source
cria um script, é como se você estivesse escrevendo aquele arquivo linha por linha no teclado. Isso significa que set -e
considerará o shell atual e que em caso de erro sairá do shell atual.
Essa é uma solução alternativa. Hoje estou com preguiça então pensei que o computador pudesse escrever ||return
para mim, ou melhor ler linha por linha o arquivo e executar assim:
#!/bin/bash
# this is the file MySource.sh
while IFS='' read -r line
do
[[ $line == \#* ]] || $line || return
done < "$1"
execute-o com. MySource.sh FileToBeSourced.sh
Se seuArquivoToBeSourced.shscript está com comandos de uma linha e deve funcionar.
Muito longe de estar pronto para ser usado em um ambiente de produção.
Teste e eventualmenteuse-o por sua conta e risco.
Ele pula as linhas que começam com #
porque deveriam causar o erro # command not found
.