bash如何处理Here-docs

ulydmbyx  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(158)

我正在用C编写一个类似bash的shell,我对here-doc有一个问题。目前我的shell只能在第一个命令中执行here-doc。
ls | << eof wc

bash结果:

> eof
0 0 0

我的结果:

> eof
10 10 63

wcls的结果,我的管道有问题,但不知道是什么问题。)
在这种情况下,我可以像ls不存在一样。
wc | << eof wc

bash结果

> eof
0 0 0

在这里,bash首先使用here-doc执行命令,然后执行第二个命令(它没有输入,因此处于冻结状态)。

我的结果

> eof

我首先执行here-doc,比如bash,eof工作,但是没有结果,然后由于第一个wc,它冻结了。
那么我可以这样处理所有的情况吗?我先用here doc执行命令,然后取消其他命令,除非它们必须崩溃(比如wc,如果它没有输入)?

t30tvxxf

t30tvxxf1#

在POSIX shell中,重定向(如here-docs)与命令相关联,管道操作符(|)分隔命令。

ls | << eof wc
eof

here-doc与第二个命令wc相关联(即使重定向操作符出现在命令名之前)。它将该命令的标准输入重定向为来自here-doc的内容。管道操作符还影响第二个命令的标准输入,因此一个重要的问题是最后应用哪个效果,POSIX为command1 | command2
command1的标准输出应连接到command2的标准输入。命令的标准输入、标准输出或两者应被视为由管道分配, 在 * 由作为命令一部分的重定向运算符指定的任何重定向之前*。
(着重号是加上去的。)不管怎么说,Bash的文档用他们自己的话也是这么说的。
对于您的示例,here-doc应该将ls的输出替换为wc的输入,就像Bash处理命令时所做的那样。
在这种情况下,我可以假装ls不存在。

wc | << eof wc

bash结果

> eof
0 0 0

在这里,bash首先使用here-doc执行命令,然后执行第二个命令(它没有输入,因此处于冻结状态)。
不完全是。heredoc属于 secondwc命令,而不是第一个,所以它是第一个挂起等待交互输入的命令。可以通过键入ctrl-D使其正常完成。
更重要的是,如果要忽略ls,那么为什么要使用两个wc命令呢?只需将ls和管道一起删除,而使用一个wc命令即可:

<<eof wc
eof

# OR, equivalently and more conventionally,

wc <<eof
eof

那么我可以这样处理所有的情况吗?我先用here doc执行命令,然后取消其他命令,除非它们必须崩溃(比如wc,如果它没有输入)?
您似乎在尝试创建特定的规则,而您应该遵守更一般的规则。每个命令都有标准的输入、输出和错误,它们最初要么从主机shell继承,要么由管道操作符指定。重定向,包括来自here-docs,都是单个命令的一部分。并且它们的效果被应用于该命令的初始标准流分配之上。当多个重定向应用于同一命令时,它们被从左到右处理。
你不能根据命令的标准流的状态来“取消”命令。它们会对接收到的流做任何事情。这可能根本就没有什么,可能因为一个错误而终止,也可能是它们本来会做的事情,还有其他可能性。shell不知道,所以它不能简化这个。

相关问题