Chame um script para outro script, mas não saia do pai se a criança chamar exit

7

first.sh :

#! /bin/ksh
echo "prova"
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
echo "ho lanciato il terzo"

second.sh :

echo "sono nel secondo script"
dosomething1
exit $?

Se second.sh detectar um erro e sair com o status -9, first.sh sairá sempre. Como posso evitar a saída do primeiro shell se o shell filho sair?

Não consigo editar second.sh .

    
por user3589887 22.07.2015 / 16:50

3 respostas

11

O que você está fazendo aqui é incluir second.sh e third.sh como sub-scripts sendo executados no mesmo processo, o que é chamado de "sourcing" na programação da shell. . ./second.sh é basicamente equivalente a incluir o texto de second.sh nesse ponto. O comando exit sai do processo, não importa se você o chama no script original ou em um script de origem.

Se tudo o que você deseja fazer é executar os comandos em second.sh e third.sh e eles não precisam acessar ou modificar variáveis e funções do script original, chame esses scripts como processos filho.

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

Se você precisar dos outros scripts para acessar variáveis e funções do script original, mas não modificá-los, chame esses scripts em subshells. Subshells são processos separados, portanto, exit apenas os processa.

#! /bin/ksh
echo "prova"
(. ./second.sh)
echo "ho lanciato il secondo"
(. ./third.sh)
echo "ho lanciato il terzo"

Se você precisar usar variáveis ou funções definidas em second.sh e third.sh no script pai, será necessário continuar terceirizando-as.

O return builtin sai apenas do script de origem e não de todo o processo - essa é uma das poucas diferenças entre incluir outro script com o comando . e incluir seu texto no script pai. Se os scripts de origem só chamarem exit no nível superior, ao contrário de funções internas, você poderá alterar exit para return . Você pode fazer isso sem modificar o script usando um alias.

#! /bin/ksh
echo "prova"
alias exit=return
. ./second.sh
echo "ho lanciato il secondo"
. ./third.sh
unalias exit
echo "ho lanciato il terzo"

Se exit também for chamado dentro de funções, não acho que haja uma maneira não complicada. Uma maneira complicada é definir uma armadilha de saída e colocar seu código lá.

#!/bin/ksh
do_first () {
  echo "prova"
  trap "after_second" EXIT
  . ./second.sh
  after_second
}
after_second () {
  echo "ho lanciato il secondo"
  trap "after_third" EXIT
  . ./third.sh
  after_third
}
after_third () {
  trap - EXIT
  echo "ho lanciato il terzo"
}
do_first
    
por 24.07.2015 / 02:31
4

Em vez de terceirizar o segundo e terceiro shell, basta executá-los como faria com qualquer outro comando. O código de saída pode ser armazenado e usado se você precisar, assim:

#! /bin/ksh
echo "prova"

# execute and capture stdout ... output of second is not seen ...
OUTPUT1=$(./second.sh)

# find out exit status of second.sh
STATUS1=$?

# ... until now
echo $OUTPUT1

# do something based on the result
if [ $STATUS1 -eq 0 ]; then 
  echo "second.sh ran successfully"
else 
  echo "second.sh crapped out"
fi

# and so on...
    
por 23.07.2015 / 02:54
0

Experimente desta forma (remova primeiro . ao chamar second.sh ):

first.sh :

#! /bin/ksh
echo "prova"
./second.sh
echo "ho lanciato il secondo"
./third.sh
echo "ho lanciato il terzo"

second.sh :

echo "sono nel secondo script"
dosomething1
exit $?

Isso ocorre porque . é shortcode para source , o que faz com que o segundo script seja incluído como parte do primeiro.

    
por 05.04.2017 / 04:47