Файловый дескриптор открывался один раз, но закрывался много раз; почему расхождение?
Я пытался использовать процесс подстановки и наткнулся на следующий пример:
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>&- закрывает дескриптор основной оболочки. Это еще одна отдельная сущность.