我尝试以这种方式执行bash脚本:
bash -s < my_script
上下文的原因是通过SSH远程运行脚本。我意识到,我想运行的脚本包含一些命令,这些命令可以在某些罕见的情况下提示用户输入。所以我决定试着去理解bash -s是如何工作的。
我写了一个简单的脚本,如下所示:
cat
echo "finished"
并得到输出:
echo "finished"
我的理解是,由于脚本本身就是标准输入,所以cat
命令只是开始阅读脚本的其余部分。
但是,如果我只是在脚本中添加一个“if”,结果就会改变。如果我运行这个:
if [ true ]
then
cat
echo "finished"
fi
我得到这个输出:
finished
我不明白是什么导致了这种差异。
2条答案
按热度按时间kr98yfug1#
bash
一次读取(至少)一个完整的 * 语句 *,不管需要多少行文件。在后一个示例中,它是整个if
语句。因此,当cat
被执行时,标准输入上已经没有任何内容可供它读取。您会看到相同的结果,例如,
因为包括
{...}
在内的所有内容都是单个(复合)语句。在第一个示例中,第一个语句本身是
cat
,将echo
语句留在标准输入中,供cat
读取。6fe3ivhb2#
为了补充chepner的答案,您可以通过尝试手动编写脚本到shell中来清楚地了解正在发生的事情。
如果您写
cat
并按enter,光标将移到下一行,并且没有提示符,这意味着shell正在等待stdin
中的一行。键入echo "finished"
并按Enter键,将输入cat
一行包含echo "finished"
,该行会立即打印回shell(当前的stdout
)。你看到的是这样的:如果您杀死它并键入
if [ true ]
,则会在新行上得到>
提示符。下一行将是一个语句,因此在一行中单独写入cat
将导致没有输出到stdout
,因为cat
没有从stdin
获得任何内容。同样,你得到的(如果你在最后给它一个EOF
)是这样的:最清楚的事情是通过按向上箭头检索最新发出的命令。您将获得:
这就是
bash
实际上看到的,并且很容易解释为什么cat
这次没有将echo "finished"
传递给stdout
。