J'ai essayé un script suivant:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
La sortie du script ci-dessus était:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
Cependant, je m'attendais à ce que le piège soit appelé à la sortie de foo1
, ce qui est appelé dans un sous-shell.
- Est-ce attendu?
- Est
trap
hérité par un sous-shell? - Si oui, dans quel cas est
trap
hérité d'un sous-shell?
Réponses:
Les gestionnaires de pièges ne sont jamais hérités par les sous-coquilles. Ceci est spécifié par POSIX :
Notez que les signaux ignorés (
trap '' SIGFOO
) restent ignorés dans le sous-shell (et dans les programmes externes lancés par le shell également).la source
set -E
pour que les sous-coquilles héritent des pièges, mais il est VRAIMENT difficile de bien faire les choses (du moins d'après mon expérience).trap
n'est pas propagé aux sous-coquilles mais certaines manières permettent à la sous-coquille de signaler les pièges du shell parent et d'autres pas. J'ai fait quelques tests sur macos avec bash.GNU bash, version 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, version 3.2.57 (1) -release (x86_64-apple-darwin16):
Il est bon de savoir que
trap_output="$(trap)"
cela fonctionnera pour capturer la sortie du piège. Je ne peux pas penser à une autre façon de le faire si cela n'a pas fonctionné à part le fairetrap >trap_output_file
pour le sortir dans un fichier (fifo ne fonctionnera pasbash 3.2.57
) et le relire ensuite avectrap_output="$(<trap_output_file)"
fifo ne fonctionnera pas
bash 3.2.57
parce qu'iltrap &
est videbash 3.2.57
mais pasbash 4.4.12
GNU bash, version 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, version 3.2.57 (1) -release (x86_64-apple-darwin16):
la source
trap
les définitions ne sont pas propagées aux sous-coques.Vérifiez par:
trap "echo bla" 1 2 3"
(trap)
la source
(trap)
comme un cas spécial, de sorte que le sous-shell peut signaler (mais pas réellement utiliser) les pièges du shell parent. Ce test n'est donc pas toujours fiable.ksh88
,bosh
(schily Bourne Shell) etheirloom-sh
. Vous avez raison:ksh93
se comporte différemment.bash
ne produit rien si vous appelez(trap)
.