retorno automático 'script de origem sobre falha de comando

2

Como posso fazer com que um script source d retorne automaticamente se algum comando dentro dele falhar?

Suponha que eu tenha um script que saia automaticamente da falha por meio de 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 será automaticamente encerrado no comando grep com falha:

box1% ./foo.env
hi
grep: 456: No such file or directory

No entanto, se eu source o script, ele sai do meu shell atual, não apenas do script 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, não sai automaticamente nem retorna automaticamente o script source 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 encontrada até agora é adicionar uma expressão return a cada linha de código no 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 os scripts source d, semelhante a como set -e funciona para não source d uns?

    
por Mr Fooz 01.06.2015 / 18:08

1 resposta

1

Quando você usa source , um script é como se estivesse escrevendo o arquivo linha a linha do teclado. Isso significa que set -e considerará o shell atual e que, no erro, ele sairá do shell atual.

Essa é uma solução alternativa. Hoje me sinto preguiça então achei que o computador pode 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 com . MySource.sh FileToBeSourced.sh

Se o seu script FileToBeSourced.sh estiver com comandos de uma linha, ele deve funcionar.
Muito longe para estar pronto para ser usado em um ambiente de produção.
Teste e, eventualmente, use por sua conta e risco .

Salta as linhas que começam com # porque devem causar o erro # command not found .

    
por 09.06.2015 / 18:50

Tags