Показать все даты в номерах недель в UNIX [закрыто]

Чтобы сохранить дескриптор файла, вы дублируете его на другом fd. Недостаточно сохранить путь к соответствующему файлу, вам нужно будет сохранить режим открытия, флаги открытия, текущую позицию в файле и так далее. И, конечно же, для анонимных каналов или сокетов это не сработает, поскольку у них нет пути.Вы хотите сохранить описание открытого файла , на которое ссылается fd, а дублирование fd фактически возвращает новый fd в то же описание открытого файла .

Чтобы скопировать дескриптор файла на другой в оболочке, подобной Bourne, синтаксис следующий:

exec 3>&1

Выше fd 1 дублируется на fd 3.

Любой fd 3, который уже был открыт ранее, будет закрыт, но обратите внимание, что fds от 3 до 9 (обычно больше, до 99 с yash ) зарезервированы для этой цели (и не имеют специального значения в отличие от 0, 1 или 2), оболочка знает, что их не использовать для собственного внутреннего бизнеса. Единственная причина, по которой fd 3 был бы открыт заранее, состоит в том, что вы сделали это в скрипте 1 , или он был пропущен вызывающей стороной.

Затем вы можете изменить stdout на что-нибудь другое:

exec > /dev/null

И позже, чтобы восстановить stdout:

exec >&3 3>&-

( 3> & - означает закрыть дескриптор файла, который нам больше не нужен).

Проблема в том, что, за исключением ksh, каждая команда, которую вы выполняете после этого exec 3> & 1 , унаследует этот fd 3. Это утечка fd. Обычно это не имеет большого значения, но это может вызвать проблемы.

ksh устанавливает флаг close-on-exec на этих fds (для fds более 2), но другие оболочки и другие оболочки не имеют возможности установить этот флаг вручную.

Для другой оболочки обходной путь заключается в том, чтобы закрыть fd 3 для каждой команды, например:

exec 3>&-

exec > file.log

ls 3>&-
uname 3>&-

exec >&3 3>&-

Громоздко.Здесь лучше всего вообще не использовать exec , а перенаправить группы команд:

{
  ls
  uname
} > file.log

Здесь оболочка заботится о сохранении stdout и его последующем восстановлении (и делает это внутренне дублируя его на fd (выше 9, выше 99 для yash ) с установленным флагом close-on-exec ).

Примечание 1

Теперь управление этими fds с 3 по 9 может быть обременительным и проблематичным, если вы используете их широко или в функциях, особенно если ваш скрипт использует сторонний код, который, в свою очередь, может использовать эти fds.

Некоторые оболочки ( zsh , bash , ksh93 , все добавили функцию (, предложенную Оливером Киддлом из zsh ) ) примерно в то же время в 2005 году после того, как это обсуждалось их разработчиками) имеют альтернативный синтаксис для назначения первого свободного fd выше 10, который помогает в этом случае:

myfunction() {
  local fd
  exec {fd}>&1
  # stdout was duplicated onto a new fd above 10, whose actual value
  # is stored in the fd variable
  ...
  # it should even be safe to re-enter the function here
  ...
  exec >&"$fd" {fd}>&-
}

1
21.01.2014, 15:34
0 ответов

Теги

Похожие вопросы