ловушка bash в фоновых функциях

528
kaligne

Вызов функции в скрипте в фоновом режиме - используя '&', функция вызывается в a subshell. Когда функция заканчивается, subshellзаканчивается, со статусом выхода. Я хотел бы поймать сигнал выхода из этого, subshellчтобы автоматически отменить файлы журнала. Мой тестовый скрипт выглядит следующим образом:

$ 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  

Вывод следующий:

$ 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 

Я ожидал, что файл third.tmpбудет удален до конца сценария. Странно то, что только второй файл .tmp был отменен:

$ ls *.tmp first.tmp third.tmp 

Я ожидаю, что третий файл будет удален только после выхода из функции. Я ожидаю, что два других файла будут удалены после завершения скрипта.

Что здесь не так?

1

1 ответ на вопрос

0
l0b0

Поскольку третья ловушка создается в подоболочке, она также активируется / запускается при выходе из этой оболочки, пытаясь удалить третий файл до его создания. Поэтому третий файл существует после того, как скрипт выполнен.

Каждый раз, когда trap […] SIGNALвы перезаписываете ловушку для этого сигнала, в верхней оболочке выживает только вторая ловушка. Поэтому первый файл существует после того, как скрипт выполнен.

А echoв ловушке или, возможно set -o xtrace, покажет вам лучше, что происходит. Вы также можете запустить trapсамостоятельно, чтобы увидеть, какие ловушки действуют.