Parar a execução quando algo é escrito para stderr

1

Eu tenho problemas com o tratamento de erros nos scripts do bash. Nenhuma das soluções que vi para manipulação de erros no bash parece funcionar até agora para este script de exemplo:

#!/usr/bin/env bash
set -euo pipefail

eval $(do_stuff)
touch file

A saída é:

./script.sh: line 4: do_stuff: command not found

Mas, mesmo assim, continua feliz e cria o arquivo, que é o que eu quero proibir. Então, em uma tentativa desesperada, percebi que posso canalizar o stderr para outro programa e terminar tudo quando ele pega alguma saída:

unbuffer ./script.sh 2>&1|{ while read stdin; do echo $stdin;killall -9 bash;done; }

No entanto, funciona aproximadamente apenas 5% do tempo. Na maioria dos casos, não consegue matar o script cedo o suficiente.

    
por gadelat 03.09.2016 / 12:10

2 respostas

1

Eu descobri como lidar elegantemente com o caso que postei:

eval() {
    if [[ -z "${@}" ]];then
        exit 1
    fi
    builtin eval "$@"
}

Substitui a implementação padrão de eval () e sai se não receber entrada. Eu não estou aceitando essa resposta, porque ela ainda não responde ao título desta pergunta.

    
por 04.09.2016 / 22:14
0

Simplesmente mude para atribuição primeiro e depois eval.

Exemplo 1 (parar se o comando de entrada for inválido):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echoasasas)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 5: echoasasas: command not found
trapped
[xiaobai@localhost ~]$ 

Exemplo 2 (parar se a saída não for um comando válido):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo xxxxx)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 6: xxxxx: command not found
trapped
[xiaobai@localhost ~]$ 

Exemplo 3 (continue a executar o próximo comando):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo ls)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
Android  CRITICAL  Documents
next
[xiaobai@localhost ~]$ 

Exemplo 4 (metade se STDERR é acionado em outro shell):

[xiaobai@localhost ~]$ cat /tmp/so.sh 
ls yyyyyy 2>/tmp/kas
[xiaobai@localhost ~]$ cat /tmp/kas
[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
echo "before"
e2=$(/bin/bash /tmp/so.sh)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
before
trapped
[xiaobai@localhost ~]$ cat /tmp/kas
ls: cannot access 'yyyyyy': No such file or directory
[xiaobai@localhost ~]$ 
    
por 03.09.2016 / 20:28