为什么read命令在sh运行时不采用交互选项?

Modified on: Sat, 30 Jun 2018 11:33:00 +0800

我想下载一个配置脚本,通过read读取一些配置参数,并执行它:

curl http://example.com/provisioning.sh | sh

问题是,使用read参数调用脚本中的-i命令以提供默认值:

read -p "Name: " -i joe name
echo $name

如果我下载脚本,设置+x权限并运行它,一切都很好。

如果我使用cat provisioning.sh | shsh provisioning.sh,它失败了:

read: Illegal option -i

如果通过sh?

运行,为什么不会读取提供默认值的支持

但无论如何,我将删除-i,留下

read -p "Name: " name
echo $name

现在,如果我通过cat provisioning.sh | sh,它什么都不做。那是为什么?

Ubuntu 14.04。

最佳答案

当您将curl的输出传递到sh时,您将使脚本文本成为shell的标准输入,并将其作为命令运行。在那之后,read就没有了。即使它是尝试,它也不会从终端输入获得任何东西,因为它没有连接到它。管道已替换sh进程的标准输入。

下一个问题是read -i POSIX sh功能,而是bash支持的扩展程序。 Ubuntu使用dash,这是一个最小的POSIX兼容shell,扩展程度最小,为/bin/sh默认情况下。这就是它特别拒绝-i选项的原因(虽然它确实支持-p)。

如果您自己使用功能更强大的外壳,可以尝试以下方法:

bash <(curl http://example.com/provisioning.sh)

bash创建一个管道,以读取curl的输出,并将其作为脚本文件参数提供。在这种情况下,脚本的标准输入仍然连接到终端,并且read将起作用(但请注意线下方的大警告)。


我还要注意curl | sh”是一般 皱起眉头,这是一个明显的安全问题,但是你最了解你的剧本所处的情况。


相关问答

添加新评论