смешивание процесса замещения и трубы в зш - PullRequest
0 голосов
/ 06 мая 2019

Используя ZSH, я пытаюсь обернуть команду sed в функцию, а затем использовать ее, смешивая каналы с подстановкой процесса.Позвольте мне объяснить на примере:

$ echo "test text" | gzip > myfile.gz
$ sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g' <(zcat myfile.gz) | more
test text
$ ncat() { sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g' $@; }
$ zcat myfile.gz | ncat | more
test text
$ ncat <(zcat myfile.gz) | more
sed: can't read /proc/self/fd/13: No such file or directory

Как вы можете видеть, в этих двух из этих трех способов использования.Последний - тот, который меня заинтриговал.(Обратите внимание, что все команды работают с bash)

Можете ли вы объяснить, почему выходные данные функции, которая использует подстановку процессов во вводе, не могут использоваться через канал?

Я не ищуОбходной путь, чтобы заставить мой пример работать.Я ищу объяснение, потому что я не смог его найти.

FYI sed здесь не имеет значения, я попытался с помощью нескольких других команд (echo, cat ...) и получил тот же результат

1 Ответ

1 голос
/ 06 мая 2019

Когда вы передаете выходные данные функции ncat, она должна выполняться в подоболочке.По какой-то причине FD, подключенный к каналу замены процесса, не наследуется этой подоболочкой.Поскольку он использует /proc/self/fd, если FD не открыт в дочернем процессе, попытка чтения из него не удалась.

Мне кажется, что это ошибка, поскольку функция должна работать аналогично внешним функциямв этом отношении.

Это не специфично для Linux, я воспроизвел проблему на MacOS под управлением zsh 5.3.

Кажется, что это происходит только тогда, когда подоболочка создается для канала.Чтобы увидеть, когда создается подпроцесс и наследуется ли FD, я изменил функцию на:

ncat() { echo $$;sh -c 'echo $PPID';echo "$@";ls /dev/fd; }

(/dev/fd - это эквивалент Mac для /proc/self/fd.)

ЕслиЯ запускаю

(ncat <(gzcat myfile.gz )) 

Скобки создают подоболочку, но FD, связанный с подстановкой процесса , равен , показанному в выводе ls /dev/fd.

...