bash + como sair do script secundário e do script principal em ambos os tempos

2

Executamos o script script1 do script script_main

script_main :

#!/bin/bash
/tmp/script1
echo $?

sleep 2
echo script ended 

script1 :

#!/bin/bash
exit 1

Como é óbvio, script1 sai com o código de saída 1 mas o script principal continuará até o final.

Minha pergunta: é possível quando script1 faz exit 1 , então também main_script será interrompido imediatamente?

    
por yael 16.01.2018 / 13:57

2 respostas

8

A maneira mais direta seria explicitamente ter o primeiro script exit se o outro script falhou. Coloque a execução do script em um condicional, como

otherscript.sh || exit 1

ou

if ! otherscript.sh ; then
      ret=$?
      echo "otherscript failed with exit code $ret. exit." >&2
      exit 1
fi

Isso permitiria que o script principal fizesse qualquer limpeza desejada ou apenas tentasse outra solução, possivelmente dependendo do código de saída do filho. Na primeira, poderíamos usar apenas || exit , para passar o código de saída da criança.

Se você deseja que o script principal seja encerrado quando o comando any começar a falhar, então set -e .

set -e
otherscript.sh
echo "this will not run if otherscript fails"

set -e não se aplica a programas que são executados dentro de construções condicionais, portanto, podemos ainda testar códigos específicos ou associá-los a || true para ignorar a falha. Mas com os pontos de saída em todos os lugares agora, poderíamos usar trap somecmd EXIT para fazer qualquer limpeza antes do shell sair, independentemente de onde isso acontece.

Ter o script interno forçando o script principal a sair também é possível, mas um pouco hostil, você não esperaria que um aplicativo comum o fizesse. Mas, se você quiser, apenas ter o roteiro interno simples que atira em seu processo pai é uma maneira:

$ cat mainscript.sh
#!/bin/bash
./otherscript.sh
echo "$0 exiting normally"
$ cat otherscript.sh
#!/bin/bash
echo "$0 kill $PPID"
kill $PPID

$ bash mainscript.sh
./otherscript.sh kill 11825
Terminated

Aqui, se você executar otherscript.sh de um shell interativo, ele tentará gravar a sessão interativa. Todas as shells que testei parecem ignorar o SIGTERM neste caso, quando executadas interativamente. Em qualquer caso, o shell principal poderia novamente trap o SIGTERM .

Em vez de gravar apenas o processo pai, você pode usar kill 0 para eliminar todos os processos no grupo de processo otherscript.sh executado. Se iniciado a partir de um shell não interativo, normalmente incluiria o pai.

    
por 16.01.2018 / 14:03
2

Você pode obter script 2 . Como:

. /tmp/script1.sh

E o código de saída será lido a partir do script2 , que encerrará o processo.

➜  /tmp cat script.sh 
#!/bin/bash

echo "Running ${0} with pid $$"
. /tmp/script1.sh
echo $?
echo "This code won't execute"
sleep 2
echo "Script ${0} ended"
echo "This code won't execute"
sleep 2

echo "Script ${0} ended"



➜  /tmp cat script1.sh 
#!/bin/bash

echo "Running ${0} with pid $$"
exit 5

Executando:

➜  /tmp ./script.sh 
Running ./script.sh with pid 10306
Running ./script.sh with pid 10306
➜  /tmp echo $?
5
    
por 16.01.2018 / 14:05