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

11

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.shdetecta um erro e sai com o status -9, first.shsai sempre. Como evitar sair do primeiro shell se o shell filho sair?

Não consigo editar second.sh.

user3589887
fonte
Aqui você está usando o .comando, que origina outro arquivo no shell atual. Não há nenhum shell filho ou subshell envolvido. Você queria executá- los second.she third.shnão fornecê-los?
Celada
sim .. devo escrever execute em vez de. ./? eu quero ignorar "exit $?" dentro do second.sh .. é possível sem editar o second.sh?
user3589887

Respostas:

13

O que você está fazendo aqui é incluir second.she third.shcomo sub-scripts em execução no mesmo processo, chamado "sourcing" na programação de shell. . ./second.shé basicamente equivalente a incluir o texto second.shnesse ponto. O exitcomando sai do processo, não importa se você o chama no script original ou em um script de origem.

Se tudo que você quer fazer é executar os comandos second.she third.she eles não precisam de acesso ou modificar as variáveis e funções a partir do roteiro original, chamar esses scripts como processos filhos.

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

Se você precisar que os outros scripts acessem variáveis ​​e funções do script original, mas não as modifique, chame esses scripts em subshells. Subshells são processos separados, portanto, exitsai somente deles.

#! /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 no second.she third.shno script pai, precisará continuar fornecendo-as.

O returnbuilt-in 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 chamarem apenas exitno nível superior, em oposição às funções internas, você poderá mudar exitpara 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 exittambém é chamado de funções internas, não acho que exista 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
Gilles 'SO- parar de ser mau'
fonte
É por esse motivo que parei de usar '.' para fonte de arquivos em um script e tente usar 'fonte' exclusivamente. A IMO deve ser considerada uma 'melhor prática' do bash, pois torna muito mais claro o que seu código está fazendo.
Mark E. Hamilton
6

Em vez de procurar o segundo e o terceiro shell, execute-os como faria com qualquer outro comando. O código de saída pode ser armazenado e usado se você precisar, da seguinte forma:

#! /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...
Dale Anderson
fonte
STATUS1=$?irá capturar o resultado do comando de eco emitido anteriormente, que é independente do resultado de ./second.sh.
Cromax 30/03
@Cromax você está completamente certo. A resposta foi editada.
Dale Anderson
0

Tente desta maneira (remova primeiro .ao ligar 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 .é um código de acesso sourceque faz com que o segundo script seja incluído como parte do primeiro.

Mojtaba Rezaeian
fonte