在 bash 脚本中从管道中使用“read”

在 bash 脚本中从管道中使用“read”

Bash 可以从管道运行脚本。一个最小的例子是:

> echo "echo hello world" | bash
hello world

curl如果您想运行从或下载的脚本,这会很方便wget

但显然,你不能read在这种脚本执行中使用。例如,

#!/bin/bash

echo 'input: '
read HELLO
echo hello: $HELLO

如果您只是从 bash 脚本文件运行上述脚本,您就可以输入$HELLO.并将echo hello: $HELLO打印结果。

如果您按照我们之前讨论的方式提供脚本:

> echo "echo 'input: '; read HELLO; echo hello: $HELLO" | bash
input: 
hello:

您根本无法获得互动。并且$HELLO仍然是空的。我也尝试过在 bash 中添加-i选项,但没有成功。

我们有什么方法可以read在管道脚本中使用吗?如何?或者,如果我们不能,为什么?

答案1

read将通过 stdin (从中读取内容)和 stderr (在其中打印-p提示符,如果有的话)与用户“交互”。

如果标准输入是脚本read将从中获取内容,导致它跳过一行:

$ echo '
read foo
what the -)(*$;?
echo "$foo"
' | bash
what the -)(*$;?

这不是一个好的做法,并且不适用于所有 shell。另请注意,当通过标准输入管道脚本时,bash必须逐字节读取它们。

在您的示例中,整个脚本是一行,因此read内置函数只会获取 EOF 而不会设置任何变量。

如果您希望read始终从控制 tty 读取数据,请显式重定向它:

read var </dev/tty

这也应该谨慎使用。如果他们必须使用expect(1)你的脚本来检测你的脚本,那么没有人会欣赏你。

相关内容