J'utilisais l'instruction "exit 1" dans mes fonctions bash pour terminer l'ensemble du script et cela a bien fonctionné:
function func()
{
echo "Goodbye"
exit 1
}
echo "Function call will abort"
func
echo "This will never be printed"
Mais je me suis alors rendu compte qu'il ne faisait pas le travail quand on l'appelait comme:
res=$(func)
Je comprends que j'ai créé un sous-shell et que la "sortie 1" abandonne ce sous-shell et non le principal ....
Mais existe-t-il un moyen d'écrire une fonction qui abandonne l'exécution entière, peu importe comment elle est appelée? J'ai juste besoin d'obtenir la valeur de retour réelle (reprise par la fonction).
Ce que vous pourriez faire, c'est enregistrer le Shell de niveau supérieur pour que le signal TERM
se termine, puis envoyer un TERM
au Shell de niveau supérieur:
#!/bin/bash
trap "exit 1" TERM
export TOP_PID=$$
function func()
{
echo "Goodbye"
kill -s TERM $TOP_PID
}
echo "Function call will abort"
echo $(func)
echo "This will never be printed"
Ainsi, votre fonction envoie un signal TERM
au shell de niveau supérieur, qui est intercepté et géré à l'aide de la commande fournie, dans ce cas, "exit 1"
.
Vous pouvez utiliser set -e
qui se ferme si une commande se termine avec un état différent de zéro :
set -e
func
set +e
Ou saisissez la valeur de retour:
(func) || exit $?
Mais existe-t-il un moyen d'écrire une fonction qui abandonne l'exécution entière, quel que soit son nom?
Non.
J'ai juste besoin d'obtenir la valeur de retour réelle (reprise par la fonction).
Vous pouvez
res=$(func)
echo $?
Un processus enfant ne peut pas forcer le processus parent à se fermer implicitement. Vous devez utiliser une sorte de mécanisme de signalisation. Les options peuvent inclure une valeur de retour spéciale ou envoyer un signal avec kill
, quelque chose comme
function child() {
local parent_pid="$1"
local other="$2"
...
if [[ $failed ]]; then
kill -QUIT "$parent_pid"
fi
}
Je suppose que c'est mieux
#!/bin/bash
set -e
trap "exit 1" ERR
myfunc() {
set -x # OPTIONAL TO SHOW ERROR
echo "Exit with failure"
set +x # OPTIONAL
exit 1
}
echo "BEFORE..."
myvar="$(myfunc)"
echo "AFTER..But not shown"