Bashfalle in Hintergrundfunktionen

667
kaligne

Aufruf einer Funktion in einem Skript im Hintergrund - mit '&' wird die Funktion in a aufgerufen subshell. Wenn die Funktion endet, subshellendet das mit einem Beendigungsstatus. Ich möchte das Exitsignal von solchen subshellabfangen, um Protokolldateien automatisch zu löschen. Mein Testskript ist wie folgt:

$ cat mscript.sh  #!/usr/bin/env sh  mout="log.out" rm -f $mout  # My testing log files tmps=(first.tmp second.tmp third.tmp)  # Traps exit signal to delete the logfile upon exiting. mtrap_tmp() { local ftmp="$1" # I create the tep file here: echo "init $ftmp" &>> $ftmp echo -e "\n($BASHPID) trapping \"$ftmp\"..." &>> $mout ## Here I trap the signal, to delete the temporary file. trap "rm -f \"$ftmp\"" EXIT echo -e " trapped tmp file \"$ftmp\" to rm" &>> $mout echo " $(ls -l $ftmp)" &>> $mout }  # I trap the first and second log files within the script's pid.  # Then I trap the third file in a subshell: mtrap_tmp $ mtrap_tmp $ mtrap_tmp $ & wait $!  # Here I want to check the temp files do exist.  # I expect the third file to be trapped in a subshell,  # and hence to be non-existent once the subshell ends,  # which should have happened after the `wait $!`:  for i in $; do echo -e "\nfinal check $i:" &>> $mout ls -l $ &>> $mout done  echo "done" exit 0  

Die Ausgabe ist wie folgt:

$ cat log.out   (10598) trapping "first.tmp"... trapped tmp file "first.tmp" to rm -rw-rw-r-- 1 anadin ctgb 15 Jul 4 15:54 first.tmp  (10598) trapping "second.tmp"... trapped tmp file "second.tmp" to rm -rw-rw-r-- 1 anadin ctgb 16 Jul 4 2017 second.tmp  (10602) trapping "third.tmp"... trapped tmp file "third.tmp" to rm -rw-rw-r-- 1 anadin ctgb 15 Jul 4 2017 third.tmp  final check first.tmp: -rw-rw-r-- 1 anadin ctgb 15 Jul 4 15:54 first.tmp  final check second.tmp: -rw-rw-r-- 1 anadin ctgb 16 Jul 4 15:54 second.tmp  final check third.tmp: -rw-rw-r-- 1 anadin ctgb 15 Jul 4 15:54 third.tmp 

Ich habe erwartet, dass die Datei third.tmpvor dem Ende des Skripts gelöscht wird. Das Merkwürdige ist, dass nur die second.tmp-Datei abgebrochen wurde:

$ ls *.tmp first.tmp third.tmp 

Ich erwarte, dass die dritte Datei erst nach dem Beenden der Funktion entfernt wird. Ich gehe davon aus, dass die beiden anderen Dateien nach Abschluss des Skripts entfernt werden.

Was ist hier falsch?

1

1 Antwort auf die Frage

0
l0b0

Da die dritte Falle in einer Subshell erstellt wird, wird es auch aktiviert / ausgeführt werden, wenn dass Shell beendet, versucht, die dritte Datei zu entfernen, bevor es erstellt worden ist. Daher ist die dritte Datei vorhanden, nachdem das Skript fertig ist.

Jedes Mal, wenn trap […] SIGNALSie die Falle für dieses Signal überschreiben, überlebt nur die zweite Falle in der oberen Schale. Daher ist die erste Datei vorhanden, nachdem das Skript fertig ist.

Ein echoin der Falle oder set -o xtracewürde Ihnen vielleicht besser zeigen, was los ist. Sie können auch trapalleine laufen, um zu sehen, welche Fallen aktiv sind.