Файловый дескриптор открывался один раз, но закрывался много раз; почему расхождение?

Я пытался использовать процесс подстановки и наткнулся на следующий пример:

exec 3>&1
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
exec 3>&- 

Насколько я понимаю, это означает следующее:

  1. Создать дескриптор файла 3 и прикрепить его к стандартному выводу.

  2. tar сожмет файлы в каталоге, определенном $directory_name и сжатый файл обозначается внутренне дескриптором файла 4,

  3. Файловый дескриптор 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>&- закрывает дескриптор основной оболочки. Это еще одна отдельная сущность.

Другие вопросы по тегам