Закриття дескриптора файлу,> & - vs <& -


49

У підручнику з bash, який я читаю, йдеться про те, що якщо ви відкриєте дескриптор файлу для читання, тобто

exec 3< echolist

Тоді ви повинні закрити так,

exec 3<&-

Однак якщо ви відкриєте дескриптор файлу для запису, його потрібно закрити так:

exec 3>&-

Однак, дивлячись в Інтернеті, я бачу, як люди відкривають файли, а потім закривають їх цим:

exec 3>&- 

ПРИМІТКА. Коли, згідно з підручником, вони повинні використовуватись exec 3<&1.

Отже, моє запитання полягає в тому, чи можна закрити всі дескриптори файлів, exec n>&-де n - номер дескриптора файлу? Незалежно від того, чи було відкрито для читання, письма чи обох?


21
Єдина відмінність між >&-і <&-- fd за замовчуванням, коли не вказано ( >&-є, 1>&-поки <&-є 0<&-). Те саме, для x>&yякого те саме, що x<&yза винятком випадків, коли xце не передбачено.
Стефан Шазелас

Відповіді:


48

Ви можете закрити дескриптор файлів, використовуючи <&-і те >&-, bashі розбере два синтаксиси як однаковий.

З файлу y.tab.c у bashвихідному коді:

5385   /* Hack <&- (close stdin) case.  Also <&N- (dup and close). */                
5386   if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND))
5387     return (character);

2
Це можна використовувати і в <>дескрипторах файлів.
CMCDragonkai

1
Ні, це неможливо, але, як це показано, 3>&-або 3<&-закрити дескриптор.
CMCDragonkai

1
Це закриття <>можна зробити тими самими способами.
CMCDragonkai

1
Я не можу зрозуміти, що ти маєш на увазі. Наведіть приклад
./

1
Я не думаю, що це я мав на увазі. Тільки те, що дескриптор файлу читання запису може бути закритий, використовуючи також 3> & - і 3 <& -.
CMCDragonkai

15

Наскільки я можу бачити, exec 3>&-і exec 3<&-те ж саме і може бути використаний на будь-якому файлі дескриптора, незалежно від того, як він був відкритий. Відповідно до розділів 2.7.6 та 2.7.5 визначення POSIX мови командної оболонки :

2.7.5 Копіювання дескриптора вхідного файлу

Оператор перенаправлення:

[n] <& слово

[... SNIP ...]

Якщо слово оцінюється на '-', дескриптор файлу n або стандартне введення, якщо n не вказано, закриваються. Спроби закрити дескриптор файлу, який не є відкритим, не становлять помилку. Якщо слово оцінює щось інше, поведінка не визначено.

2.7.6 Дублювання дескриптора вихідного файлу

Оператор перенаправлення:

[n]> & слово

[... SNIP ...]

Якщо слово оцінюється на '-', дескриптор файлу n або стандартний висновок, якщо n не вказано, закрито. Спроби закрити дескриптор файлу, який не є відкритим, не становлять помилку. Якщо слово оцінює щось інше, поведінка не визначено.

Зауважте, що жодне не вказує нічого про те, як спочатку відкривався дескриптор файлу n. Це відповідає тому, що close (2) не переймається тим, як ви відкрили файл.

Швидкий перелік наступного:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4<&-

проти цього:

exec 3< /etc/passwd
exec 4> foo
exec 3<&-
exec 4>&-

показує, що в обох випадках Баш робить точно те саме.

Два поважно цікавих факти


1
Сторінка bash man зазначає закриття, цитуючи ваше посилання: Якщо слово оцінюється на '-', дескриптор файлу n закритий.
студог

@studog Дякуємо за перевірку джерела! Я думаю, що тут сталося - я переглядав локальну сторінку для Bash 3, а потім пов'язував з Інтернет-документацією, яка була для Bash 4. У старій документації Bash 3 фразу про закриття було опущено з опису [N]>&WORD: git .savannah.gnu.org / cgit / bash.git / tree / doc /…
Стівен D

7

Приклад розуміння cuonglm щодо закриття '<>' FD.

Про це йдеться в Посібнику з розширеного сценарію баштів за адресою http://tldp.org/LDP/abs/html/io-redirection.html

[j]<>filename
  #  Open file "filename" for reading and writing,
  #+ and assign file descriptor "j" to it.
  #  If "filename" does not exist, create it.
  #  If file descriptor "j" is not specified, default to fd 0, stdin.
  #
  #  An application of this is writing at a specified place in a file. 
  echo 1234567890 > File    # Write string to "File".
  exec 3<> File             # Open "File" and assign fd 3 to it.
  read -n 4 <&3             # Read only 4 characters.
  echo -n . >&3             # Write a decimal point there.
  exec 3>&-                 # Close fd 3.
  cat File                  # ==> 1234.67890
  #  Random access, by golly.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.