shell 在bash -s中使用交互式命令

e7arh2l6  于 2023-05-07  发布在  Shell
关注(0)|答案(2)|浏览(197)

我尝试以这种方式执行bash脚本:

bash -s < my_script

上下文的原因是通过SSH远程运行脚本。我意识到,我想运行的脚本包含一些命令,这些命令可以在某些罕见的情况下提示用户输入。所以我决定试着去理解bash -s是如何工作的。
我写了一个简单的脚本,如下所示:

cat
echo "finished"

并得到输出:

echo "finished"

我的理解是,由于脚本本身就是标准输入,所以cat命令只是开始阅读脚本的其余部分。
但是,如果我只是在脚本中添加一个“if”,结果就会改变。如果我运行这个:

if [ true ]
then
        cat
        echo "finished"
fi

我得到这个输出:

finished

我不明白是什么导致了这种差异。

kr98yfug

kr98yfug1#

bash一次读取(至少)一个完整的 * 语句 *,不管需要多少行文件。在后一个示例中,它是整个if语句。因此,当cat被执行时,标准输入上已经没有任何内容可供它读取。
您会看到相同的结果,例如,

{
  cat
  echo "finished"
}

因为包括{...}在内的所有内容都是单个(复合)语句。
在第一个示例中,第一个语句本身是cat,将echo语句留在标准输入中,供cat读取。

6fe3ivhb

6fe3ivhb2#

为了补充chepner的答案,您可以通过尝试手动编写脚本到shell中来清楚地了解正在发生的事情。
如果您写cat并按enter,光标将移到下一行,并且没有提示符,这意味着shell正在等待stdin中的一行。键入echo "finished"并按Enter键,将输入cat一行包含echo "finished",该行会立即打印回shell(当前的stdout)。你看到的是这样的:

[xxx@yyy ~]$ cat
echo "finished"
echo "finished" # this one was printed by cat
# and now your cursor is here

如果您杀死它并键入if [ true ],则会在新行上得到>提示符。下一行将是一个语句,因此在一行中单独写入cat将导致没有输出到stdout,因为cat没有从stdin获得任何内容。同样,你得到的(如果你在最后给它一个EOF)是这样的:

[xxx@yyy ~]$ if [ true ]
> then
> cat
> echo "finished"
> fi # here you press enter, cursor goes to newline, then CTRL+D to feed an EOF
finished

最清楚的事情是通过按向上箭头检索最新发出的命令。您将获得:

[xxx@yyy ~]$ if [ true ]; then cat; echo "finished"; fi

这就是bash实际上看到的,并且很容易解释为什么cat这次没有将echo "finished"传递给stdout

相关问题