Файловый дескриптор открывался один раз, но закрывался много раз; почему расхождение?
Я пытался использовать процесс подстановки и наткнулся на следующий пример:
exec 3>&1
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
exec 3>&-
Насколько я понимаю, это означает следующее:
Создать дескриптор файла
3
и прикрепить его к стандартному выводу.tar
сожмет файлы в каталоге, определенном$directory_name
и сжатый файл обозначается внутренне дескриптором файла4
,Файловый дескриптор
4
прикреплен к стандартному выводустандартный вывод прикреплен к дескриптору файла
3
и дескриптор файла3
закрыто.
Но снова в bzip2
дескриптор файла снова закрывается и в последней строке exec
команда также закрывает дескриптор 3
, Там я заблудился, почему один и тот же файловый дескриптор закрывается 3 раза?
1 ответ
Это разные дескрипторы. Смотрите этот хороший ответ. Это говорит:
[Ребенок] наследует копию дескриптора файла. Таким образом, закрытие дескриптора в дочернем элементе закроет его для дочернего элемента, но не для родительского, и наоборот.
В случае как tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&-
Перенаправления обрабатываются оболочкой до tar
даже запускается, но принцип тот же: эти дескрипторы не те из основной оболочки. когда tar
начинается (строго: когда копия оболочки в конечном итоге исполняется на tar
), его /dev/fd/*
ссылки уже подготовлены и нет /dev/fd/3
,
Таким же образом bzip2
находит свои собственные дескрипторы подготовлены. Они могут ссылаться на те же файлы, что и дескрипторы некоторых других процессов, но они являются отдельными объектами.
Имейте в виду, что каждый процесс видит свои собственные дескрипторы в /dev/fd/
Полезный трюк. Если вы считаете, /proc/<PID>/fd/
каталоги, станет понятнее, дескрипторы идут по PID.
в заключение exec 3>&-
закрывает дескриптор основной оболочки. Это еще одна отдельная сущность.