Как надежно удалить все временные файлы, созданные в скрипте?

2252
kaligne

Можно ли перехватить выход / возврат функции? Для программы, которую я мог сделать

trap -- "clean_this" EXIT 

Это будет выполнять функцию clean_thisпри выходе из программы. Я хотел бы сделать что-то в этом роде при выходе из функции.

function myfunc() { echo "I'm a function" }  myfunc & wait $! 

Я выполняю функцию в подоболочке, и я хотел бы перехватить ее выход / возврат. Это возможно?


EDIT1

Вот моя цель

У меня есть один скрипт для управления временными файлами:

cat tempfiles.sh  ## List of temp files tmp_tmp_files=()  ## Adds a file to the list of temp files function tmp_add_file() { tmp_tmp_files+=("$1") }  ## Resets the list of temp files function tmp_reset_files() { tmp_tmp_files=() }  ## Removes the list of temp files  function tmp_rm_all() { rm -f "$" }  ## Removes all temp files on exit and sigint trap "tmp_rm_all" EXIT SIGINT 

Вот мой основной сценарий:

cat mscript.sh  source tempfiles.sh  ## ## Creates a temp file and writes in it mfunc() { local tempfile=$(mktemp) tmp_add_file $tempfile echo "something" >> $tempfile echo "($BASHPID) - tempfiles: $" }  ## Creates a temp file in main shell mfunc  ## Creates a temp file in a subshell (mfunc) 

Я называю основной сценарий:

$ bash mscript.sh  (92250) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj (92254) - tempfiles: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq 

Я проверяю временные файлы:

$ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj cat: /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.oRlUxEBj: No such file or directory  $ cat /var/folders/9k/h6hn75090_n8z0kythwmwqp96_0t2m/T/tmp.s1iIvtpq  something 

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

mfunc() { local tempfile=$(mktemp) tmp_add_file $tempfile1 echo "something" >> $tempfile echo "tempfiles: $" ## Process things... rm $tempfile1 } 

Но я хотел бы знать, существует ли элегантный способ их subshellsавтоматического удаления (временных файлов, созданных в ), как я делаю с traps при выходе из программы.

Итак, мой вопрос: возможно ли это сделать? Какие могут быть альтернативы?

0
Чего ты пытаешься достичь? Функция, помещенная в фоновый режим, может вызывать другую функцию, поэтому позвольте `myfunc` вызвать` clean_this` в самом конце. Или вызывайте их как ` & `. [Вам действительно нужна ловушка?] (Https://meta.stackexchange.com/a/66378/355310) Kamil Maciorowski 7 лет назад 0
Спасибо за ответ. Здесь я отредактировал свой вопрос и написал свою цель. Ну, конечно, я могу избежать ловушек, но с тех пор, как я начал их использовать, если я могу делать то, что хочу, простым способом ... Почему бы и нет kaligne 7 лет назад 0

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

1
Kamil Maciorowski

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

Ваш подход некорректен и его будет сложно поддерживать, потому что наследование идет в одну сторону. Каждый (mfunc)наследует tmp_tmp_filesи работает со своей копией массива. Нет способа изменить оригинал, tmp_tmp_filesиспользуемый в основном скрипте. Поэтому основной скрипт не может очистить все, он просто не обладает достаточным количеством информации.

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

Альтернативный подход: временный каталог

  1. Вместо создания массива создайте каталог и запомните его путь. Сделайте это один раз в начале, и exportесли вам нужно:

    tempdir=$(mktemp -d mscript.XXXXXXXXXX) 
  2. Создайте каждый временный файл во временном каталоге, например так:

    tempfile=$(mktemp -p "$tempdir") 
  3. В конце удалите весь каталог, независимо от того, были ли определенные файлы созданы основным сценарием или подоболочкой, или даже какой-то сторонней программой. Вы можете использовать ловушку для выполнения этого шага. Просто:

    rm -r "$tempdir" 
спасибо, это то, что я делаю сейчас. Итак, я полагаю, что нет никакого способа вызвать что-либо, как только функция останавливается. Правильно? kaligne 7 лет назад 0
@ user3298319 Я точно не знаю. Случилось так, что ваш вопрос был [проблема XY] (https://meta.stackexchange.com/a/66378/355310), и я ответил, чтобы решить вашу настоящую проблему. Я также изменил заголовок, так что теперь он бесполезен для пользователей, заинтересованных в ловушках; это полезно в теме временных файлов. Моя точка зрения: этот вопрос развился. Если вы хотите исследовать ловушки, вы можете задать другой вопрос и объяснить там, что вы спрашиваете из любопытства. Это не может быть хорошо принято, хотя. Сайт концентрируется на решении практических задач, и пользователи, как и я, склонны предоставлять вам надлежащие инструменты. Kamil Maciorowski 7 лет назад 0

Похожие вопросы