TGViewer
Bash Days | Linux | DevOps Bash Days | Linux | DevOps @bashdays · 23.6K subscribers
Post #1133 9.79K
Живое вмешательство. File descriptors и GDB.

🔤🔤🔥🔤🔤🔤🔤🔤🔤🔤

Написать статью для #балансбатл навеяли 2 события, разной давности:
ㅤ
1. Вопрос на собесе со мной в качестве соискателя: "Что такое файл в Linux?"
2. Прочтение поста Романа Один рубит - семеро в хуй трубят.

Что такое файл в Linux читателю я предлагаю изучить самостоятельно, или Роману раскрыть эту тему подробнее. Ключевое: файл - это некая абстракция для всего, что можно читать или записывать. Идея - "В linux все - это файл".

Далее, эту идею постараюсь протянуть тонкой нитью через статью Один рубит - семеро в хуй трубят.

Кратко: на собесе Серёжа удалил /var/log/nginx/access.log, далее обсуждается несколько моментов:

а) "Серёжа, а почему файл access.log пропал и больше не появляется? Nginx то в данный момент работает, запросы на него идут." (с)

б) "Где карта Билли? Нам нужна карта!" (с)

в) "Внятного ответа не получил, что-то на уровне — он появится спустя сутки, когда logrotate отработает. Дада… будем сутки без логов сидеть." (с)

Отвечаем на вопросы и решаем проблемы:

a) удаление файлов в Linux лишь убирает название файла из файла каталога, но inode с данными остаётся, пока его держит открытым хоть один процесс.

Так что это не проблема. Идем дальше.

б) и в) Помогаем Билли с картой и не сидим сутки без логов.

Пока процесс открыт он продолжает держать fd (файловые дескрипторы), даже если файл удален.

1. Проверим утверждение. Пишем скрипт:

#!/bin/bash

echo $$ > /tmp/nginx.pid
exec 3> /tmp/access.log
while true; do
echo "$(date) Где карта Билли? Нам нужна карта!!!" >&3
sleep 1
done


2. Запускаем, читаем логи:

$ ./simple.sh &
[2] 13502
$ tail -f /tmp/access.log
Sun Aug 10 23:15:42 MSK 2025 Где карта Билли? Нам нужна карта!!!
Sun Aug 10 23:15:43 MSK 2025 Где карта Билли? Нам нужна карта!!!


3. Удалим файл.

rm /tmp/access.log


4. Процесс продолжает писать в файл. Смотрим (PID знаем, смотри выше):

$ ls -l /proc/13502/fd
total 0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 0 -> /dev/pts/0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 1 -> /dev/pts/0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 2 -> /dev/pts/0
lr-x------ 1 aflw aflw 64 Aug 10 23:23 255 -> /home/aflw/planka-backup/simple.sh
l-wx------ 1 aflw aflw 64 Aug 10 23:23 3 -> '/tmp/access.log (deleted)'


или так (тут PID схватим по другому), через watch наглядно:

watch -n1 -d "lsof -p $(cat /tmp/nginx.pid) | grep deleted"

Every 1.0s: lsof -p 13502 | grep deleted
simple.sh 13502 aflw 3w REG 8,32 188825 17988 /tmp/access.log (deleted)


5. Билли возвращает карту:

cp /proc/13502/fd/3 /tmp/access.log.restored


Вуаля! Дескриптор НЕ потерялся, процесс не сошел с ума, логи восстановлены.

—

Что дальше? Файл то удален!

Представим, что у нас серьезный PROD, тяжеленный "Билли"нговый демон СверхБербанка, где перезапуск = потеря соединений и часовое восстановление сессий!

Подкинем новый файл /tmp/access_new.log без перезапуска процесса. Будем использовать отладчик gdb.

1. Запускаем

sudo gdb -p $(cat /tmp/nginx.pid)


2. Выполняем внутри gdb:

GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
# открываем новый файл для логов
(gdb) call (int) open("/tmp/access_new.log", 66, 0644)
$1 = 4 # новый файловый дескриптор

(gdb) call (int) dup2(4, 3) # дублируем fd 4 в позицию 3.
$2 = 3

(gdb) call (int) close(4) # Закрываем временный fd 4
$3 = 0

(gdb) detach
Detaching from program: /usr/bin/bash, process 13502
[Inferior 1 (process 13502) detached]

(gdb) quit


3. Проверяем файловые дескрипторы процесса и лог:

$ ls -l /proc/13502/fd
total 0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 0 -> /dev/pts/0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 1 -> /dev/pts/0
lrwx------ 1 aflw aflw 64 Aug 10 23:23 2 -> /dev/pts/0
lr-x------ 1 aflw aflw 64 Aug 10 23:23 255 -> /home/aflw/planka-backup/simple.sh
lrwx------ 1 aflw aflw 64 Aug 10 23:23 3 -> /tmp/access_new.log


$ tail -f /tmp/access_new.log
Mon Aug 11 00:17:54 MSK 2025 Где карта Билли? Нам нужна карта!!!


На этом все. Процесс пишет в новый файл с тем же дескриптором.

🛠 #балансбатл
—
✅ @bashdays ✅ @linuxfactory ✅ @blog
More from @bashdays
  1. Sep 25, 2026ИИ-агент может быть у каждого: создать персонального помощника можно без настройки серверо…
  2. Sep 25, 2026🚀 Zabbix 8.0 на подходе. Запланируйте обучение команды уже сейчас В ближайшее время ожида…
  3. Sep 24, 2026✨ Как настроить PostgreSQL для продакшен-нагрузок При переходе к продакшен-нагрузкам важно…
  4. Sep 24, 2026Post #1565
  5. Sep 24, 2026Траблшутинг - мастхэв компетенция для инженера В Rebrain траблшутинги проводят уже несколь…
  6. Sep 23, 2026Здрасти приехали, решил я в кой-то веке воспользоваться услугами Codex, создал аккаунт, по…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →