Довольно часто мы запускаем исполняемый файл, который должен записывать / читать некоторые временные файлы. Обычно мы создаем временный каталог, запускаем там исполняемый файл и удаляем каталог, когда скрипт завершен.
Я хочу удалить каталог, даже если исполняемый файл убит. Я попытался обернуть это в:
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary
Когда my_binary
умирает, последний процесс, в котором ядро удалит каталог, так как скрипт является последним процессом, удерживающим это inode
; но я не могу создать файл в удаленном каталоге.
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt
выходы touch: file.txt: No such file or directory
Лучшее, что я могу придумать, это удалить временный каталог, когда процесс умирает, перехватывая наиболее распространенные сигналы, и запустить процесс очистки с помощью cron:
#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary
Есть ли какой-нибудь простой способ создать действительно временный каталог, который автоматически удаляется при смерти текущего двоичного файла, несмотря ни на что?
cleanup
может быть выполнено до выполнения mktemp. Возможно, вы захотите,unset dir
прежде чем устанавливать ловушку.Ответы:
Ваш последний пример - самый надежный.
Это будет выполняться до тех пор, пока сама оболочка все еще функционирует. По сути, SIGKILL - единственное, с чем он не справится, так как оболочка принудительно завершается.
(возможно, SIGSEGV тоже не пробовал, но его можно поймать)
Если вы не оставляете это на усмотрение оболочки, то единственная другая возможная альтернатива - заставить ядро это делать. Обычно это не ядро, но есть один трюк, но у него есть свои проблемы:
По сути, вы создаете монтирование tmpfs, а затем ленивый размонтируете его. Как только скрипт будет выполнен, он будет удален.
Недостатком, кроме того, что он слишком сложен, является то, что если сценарий умирает по какой-либо причине перед размонтированием, у вас не будет монтирования.
Это также использует tmpfs, который будет использовать память. Но вы можете сделать процесс более сложным и использовать циклическую файловую систему, а также удалить файл, поддерживающий его после его монтирования.
В конечном счете,
trap
это лучшее, что касается простоты и безопасности, и если ваш сценарий не получает SIGKILLed регулярно, я бы придерживался этого.источник
mktemp
или после нее? Я бы подумал, что если ловушка будет помещена непосредственно передmktemp
, то даже если сигнал выхода был получен после ловушки и передmktemp
, все, что могло бы произойти, - это то, чтоrm -rf
команда будет запущена с пустым аргументом, ничего не добившись. Но если бы ловушка была послеmktemp
, мог бы быть крошечный окошко шанса, что временный каталог останется. Или я совсем с базы?Вы можете использовать ожидание встроенной команду ждать фонового задание до конца:
источник
blah; rm -rf $DIR
, верно? Проблема в том, что он пропустит $ DIR, если скрипт будет убит.