Как надежно удалить все временные файлы, созданные в скрипте?
Можно ли перехватить выход / возврат функции? Для программы, которую я мог сделать
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 "${tmp_tmp_files[@]}"
}
## 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: ${tmp_tmp_files[@]}"
}
## 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: ${tmp_tmp_files[@]}"
## Process things...
rm $tempfile1
}
Но я хотел бы знать, есть ли элегантный способ получить их (временные файлы, созданные в subshells
) удаляется автоматически, как и я с trap
s при выходе из программы.
Итак, мой вопрос: возможно ли это сделать? Какие могут быть некоторые альтернативы?
1 ответ
Подоболочки наследуют окружающую среду или ее часть. Похоже, что когда вы выполняете функцию в подоболочке, вам не нужно экспортировать переменные (сравните: нет необходимости в экспорте при запуске функций в подоболочке). Там могут быть некоторые случаи, когда вам нужно export
но давайте сосредоточимся на вашем примере.
Ваш подход некорректен и его будет сложно поддерживать, потому что наследование идет в одну сторону. каждый (mfunc)
наследуется tmp_tmp_files
и работает со своей собственной копией массива. Там нет никакой возможности изменить оригинал tmp_tmp_files
используется в основном скрипте. Поэтому основной скрипт не может очистить все, он просто не обладает достаточным количеством информации.
Если вы решите очистить функцию subhelled, вам нужно будет обратить внимание и отделить временные файлы функции от временных файлов основного скрипта. Преждевременное удаление последнего может привести к сбою вашего скрипта.
Альтернативный подход: временный каталог
Вместо создания массива создайте каталог и запомните его путь. Сделайте это один раз в начале и
export
если тебе надо:tempdir=$(mktemp -d mscript.XXXXXXXXXX)
Создайте каждый временный файл во временном каталоге, например так:
tempfile=$(mktemp -p "$tempdir")
В конце удалите весь каталог, независимо от того, были ли определенные файлы созданы основным сценарием или подоболочкой, или даже какой-то сторонней программой. Вы можете использовать ловушку для выполнения этого шага. Просто:
rm -r "$tempdir"