ㅤ
Как говорится — Волков бояться, в лесу не ебаться!
Пишем подопытный скрипт:
#!/usr/bin/env bash
set -e
temp=$(mktemp)
echo "Создал файл: $temp"
false
echo "Удаляю файл"
rm -f "$temp"
Чмодим, запускаем, ага скрипт упал на
false, но успел создать временный файл в папке /tmp == /tmp/tmp.oWQ0HiYxSV. И он не удалился. Скрипт вернул статус == 1;Код выходы проверить так:
echo "код: $?"
Здесь я взял синтетику, показать наглядно этот случай. Суть «темки» — подчищать за собой, при любых обстоятельствах, даже если скрипт вернул ошибку, либо завершился успешно.
Снова изобретать велосипед? Неа! Всё это работает из коробки.
#!/usr/bin/env bash
set -e
temp=$(mktemp)
echo "Создал файл: $temp"
trap 'echo "Удаляю $temp"; rm -f "$temp"' EXIT
false
В этом случае скрипт также вернет код
1, но временный файл будет удалён при любом раскладе.Нихуя непонятно, но очень интересно.
Смотри —
trap вызывает rm ПРИ ВЫХОДЕ ИЗ СКРИПТА. И похуй с каким статусом был завершен скрипт. Временный файл будет гарантированно удалён.Давай подключим
strace:strace -e trace=process,signal bash -c '
tmp=$(mktemp)
trap "rm -f $tmp" EXIT
echo "tmp=$tmp"
'
В выхлопе видим:
openat(AT_FDCWD, "/tmp/tmp.Dn2qG3uK9V", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
rt_sigaction(SIGINT, {sa_handler=0x...}, NULL, 8) = 0
rt_sigaction(SIGTERM, {sa_handler=0x...}, NULL, 8) = 0
unlink("/tmp/tmp.Dn2qG3uK9V") = 0
exit_group(0) = ?
openat(... O_EXCL) — это mktemp, создающий файл атомарноrt_sigaction() — Bash ставит ловушки для сигналовunlink() — это и есть выполнение trapexit_group(0) = ? — завершает процессТо есть Bash вызывает
rm/unlink() ДО выхода из процесса.Почему trap срабатывает?
Если скрипт упал или получил сигнал
kill -TERM <pid>, то на уровне Bash:— в обработчике сигнала вызывается registered trap
— затем Bash падает/выходит
—
trap УЖЕ успел выполнить команду очисткиtrap выполняется ДО того, как процесс отдаст SIGTERM ядру, если только ловушка для этого сигнала была установлена.Да банально при выполнении скрипта ты нажал
CTRL+C, скрипт остановился, НО временные файлы сразу подчистились.➡️ Про exit codes (коды выхода) писал тут.
➡️ Про сигналы писал ранее тут и тут и тут и тут.
Вот такие пироги!
С пятницей и хороших тебе предстоящих выходных!
🛠 #bash #debug #strace
—
💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog