Некоторые оболочки, например bash
, поддерживают замену процесса, которая представляет собой способ представления результатов процесса в виде файла, например:
$ diff <(sort file1) <(sort file2)
Однако эта конструкция не POSIX и, следовательно, не переносимая. Как можно заменить процесс на POSIX- дружественный метод (т. Е. Тот, который работает в /bin/sh
) ?
примечание: вопрос не в том, как различить два отсортированных файла - это только надуманный пример, демонстрирующий подстановку процесса !
shell
pipe
posix
process-substitution
starfry
источник
источник
/bin/sh
должен быть оболочкой POSIX, только для того, чтобы где-то была вызвана команда,sh
которая в правильной среде совместима с POSIX. Например, в Solaris 10/bin/sh
это не оболочка POSIX, это древняя оболочка Bourne, и оболочка POSIX включена/usr/xpg4/bin/sh
.Ответы:
Эта функция была введена
ksh
(впервые задокументирована в ksh86) и использовала эту/dev/fd/n
функцию (добавлена независимо в некоторых BSD и системах AT & T ранее). Вksh
и до ksh93u, он не будет работать , если ваша система не имеет поддержки / DEV / FD / н. zsh, bash иksh93u+
выше могут использовать временные именованные каналы (именованные каналы добавлены в SysIII, я считаю), где / dev / fd / n недоступны.В системах, где это возможно (POSIX не указывает их), вы можете выполнить подстановку процесса самостоятельно ( ) с помощью:
/dev/fd/n
diff <(cmd1) <(cmd2)
Однако это не работает
ksh93
в Linux, так как там, каналы оболочки реализованы с парами сокетов вместо каналов и открытием,/dev/fd/3
где fd 3 указывает на сокет, не работает в Linux.Хотя POSIX не указывает . Он определяет именованные каналы. Именованные каналы работают как обычные каналы, за исключением того, что вы можете получить к ним доступ из файловой системы. Проблема здесь заключается в том, что вам нужно создавать временные и впоследствии очищать, что трудно сделать надежно, особенно учитывая, что POSIX не имеет стандартного механизма (такого как в некоторых системах) для создания временных файлов или каталогов, и делает обработку сигналов переносимой. (убирать при повешении или убивать) также трудно сделать переносимым.
/dev/fd/n
mktemp -d
Вы могли бы сделать что-то вроде:
(не заботясь об обработке сигналов здесь).
источник
/dev/fd/n
пример. Почему дескриптор 4 закрывается дважды? (И дескриптор 3). Я потерян.cmd2
(dup2(0,4)
на внешнем{...}
, восстановлен с помощьюdup2(4,0)
для внутреннего{...}
).mktemp -d
чтобы убедиться, что вы можете получить FIFO, поскольку никто не должен писать в ваш новый случайный временный каталог.mktemp -d
. Но это не стандартная команда / POSIX.При необходимости, чтобы избежать потери переменной в полезной
cmd | while read A B C
, вместо:вы можете использовать:
Итак, чтобы ответить на вопрос:
источник