— Отличный вопрос! (радостно потираю руки) Давай разберём всю магию файловых дескрипторов в Linux!
FD | Название | Описание | Пример |
---|---|---|---|
0 |
stdin (standard input) | Ввод данных | read var |
1 |
stdout (standard output) | Вывод данных | echo "text" |
2 |
stderr (standard error) | Вывод ошибок | ls /nonexistent |
# FD 3 - дополнительный вывод
exec 3> log.txt
echo "Сообщение в FD3" >&3
# FD 4 - для разделения потоков
exec 4> errors.txt
some_command 2>&4
#!/bin/bash
# Создаем несколько потоков
exec 3> normal.log
exec 4> debug.log
exec 5> trace.log
echo "Обычное сообщение" >&1 # stdout
echo "Предупреждение" >&2 # stderr
echo "Нормальный лог" >&3 # FD3
echo "Отладочная информация" >&4 # FD4
echo "Трассировка" >&5 # FD5
# Закрываем когда не нужны
exec 3>&-
exec 4>&-
Синтаксис | Значение | Пример |
---|---|---|
&1 |
Ссылка на FD1 (stdout) | 2>&1 |
&0 |
Ссылка на FD0 (stdin) | </dev/null |
&- |
Закрыть дескриптор | 2>&- |
Файл | Назначение |
---|---|
/dev/null |
"Чёрная дыра" (всё пропадает) |
/dev/zero |
Источник нулевых байт |
/dev/random |
Генератор случайных чисел |
/dev/stdin |
Явное указание stdin |
/dev/fd/N |
Доступ к дескриптору N |
# Вывод
command > file # stdout в файл (перезапись)
command >> file # stdout в файл (добавление)
command 2> file # stderr в файл
command &> file # оба потока в файл
# Ввод
command < file # stdin из файла
command << text # here-document
command <<< "text" # here-string
# Комбинированные
command > file 2>&1 # оба потока в файл
command 2>&1 > file # опасно! другой порядок
command > file1 2> file2 # раздельные файлы
# Обмен потоками местами
exec 3>&1 1>&2 2>&3
# Временное перенаправление
{ echo "В stdout"; echo "В stderr" >&2; } 2> errors.log
# Множественные перенаправления
command 1> normal.log 2> errors.log 3> debug.log
#!/bin/bash
# Создаем паутину из дескрипторов
exec 3>&1
exec 4>&2
exec 5>&3
exec 6>&4
echo "FD1" >&1 # stdout
echo "FD3" >&3 # тоже stdout (через FD3)
echo "FD5" >&5 # снова stdout (через FD5→FD3→FD1)
#!/bin/bash
# Полное логирование с разделением потоков
exec 3>> /var/log/myapp.log
exec 4>> /var/log/myapp.errors
{
echo "Начало работы"
some_command
another_command
} 1>&3 2>&4
exec 3>&- # закрываем
exec 4>&-
# Полное отключение от терминала
daemon_command > /dev/null 2>&1 </dev/null &
# Посмотреть открытые дескрипторы процесса
ls -la /proc/$$/fd/
# Или для любого процесса
ls -la /proc/PID/fd/
— Вот такая магия дескрипторов! 🎩✨ Теперь ты можешь управлять потоками как настоящий шелли-ниндзя!
P.S. Кстати, &11
действительно будет ссылкой на FD11, если он открыт — но так делать не рекомендуется из-за непредсказуемости.