在ZSH中混合过程替代和管道



使用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

您可以看到,在这三种用法中,这2个用途。最后一个是在这里吸引我的人。(请注意,所有命令都可以使用bash(

您能解释为什么在输入中使用过程替换的函数的输出,无法通过管道使用?

我不是在寻找解决方法来使我的榜样起作用。我正在寻找一个解释,因为我找不到一个。

fyi sed在这里不相关,我尝试了多个其他命令(echo,cat ...(,并获得了相同的结果

ncat函数输出输出时,必须在子壳中运行。由于某种原因,该子壳并未继承与过程替换管相关的FD。由于它使用/proc/self/fd,因此如果FD在子过程中未打开,则尝试从中阅读的尝试失败。

对我来说似乎是一个错误,因为在这方面,功能应与外部功能相似。

这不是Linux特定的,我在运行ZSH 5.3的MACOS上重现了问题。

这似乎只有在为管道创建子壳时才发生。要查看何时创建子过程以及是否继承了FD,我将功能更改为:

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

(/dev/fd/proc/self/fd的MAC。(

如果我运行

(ncat <(gzcat myfile.gz )) 

括号创建一个子壳,但是与过程替换相关的FD ls /dev/fd输出中显示。

最新更新