使用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
输出中显示。