在通过管道传输给解释器的脚本中读取用户输入

时间:2014-10-19 23:21:37

标签: bash

我希望用bash脚本获取用户输入,该脚本首先通过wget下载(使用cat在下面的代码中代理),然后通过stdin输入bash。我认为它会很简单,但它不起作用。

脚本(在名为gistfile2.sh的文件中):

#!/bin/bash

echo -n "Enter path: "
read path
echo $path

我如何运行它:

root@precise32:/tmp# cat (or wget -qO-) gistfile2.sh | bash 
Enter path: root@precise32:/tmp#

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

首先,让我们看看管道是如何工作的:

何时

foo | bar

运行bar,bar的标准输入已连接到foo的标准输出。 这意味着bar无法知道它将继承的stdin描述符,如果不是管道覆盖它的话。此信息丢失,无法恢复。

然而,在实践中,人们经常会猜到:如果stderr仍然是TTY句柄,那么可以为stdin打开;如果操作系统提供了诸如/dev/tty之类的工具来处理进程控制tty,那就更好了。


所以:

如果您的标准输入(FD 0)已被管道覆盖,您可以尝试从/dev/tty读取。 这绝不是保证可行的,而且是依赖于平台的功能 - 但如果它不起作用,那么你将会退回其他hackery,例如希望stderr没有被重定向。

阅读/dev/tty

read path </dev/tty || { rc=$?; echo "Unable to read from TTY" >&2; exit "$rc"; }

从stderr读取(假设它连接到读/写FD到你的TTY - 一个很大的假设):

read path <&2 || { rc=$?; echo "stderr not attached to a TTY?" >&2; exit "$rc"; }