在从管道执行的bash脚本中使用read-p

在从管道执行的bash脚本中使用read-p,bash,pipe,wget,stdin,Bash,Pipe,Wget,Stdin,我提前道歉-我没有充分理解我所问问题背后的想法,无法理解为什么它不起作用(我不知道我需要学习什么。我首先搜索了stack exchange的答案——我找到了一些可能相关的信息,但没有很好地解释这些概念,因此我不知道如何构建一个有效的解决方案。我一直在搜索谷歌,但没有找到任何信息,以我能理解的方式准确描述正在发生的事情。任何背景概念方面的指导,如果能帮助我理解正在发生的事情,我将不胜感激 是否可以在从管道执行的bash脚本中获取用户输入? 例如: wget -q -O - http://myscr

我提前道歉-我没有充分理解我所问问题背后的想法,无法理解为什么它不起作用(我不知道我需要学习什么。我首先搜索了stack exchange的答案——我找到了一些可能相关的信息,但没有很好地解释这些概念,因此我不知道如何构建一个有效的解决方案。我一直在搜索谷歌,但没有找到任何信息,以我能理解的方式准确描述正在发生的事情。任何背景概念方面的指导,如果能帮助我理解正在发生的事情,我将不胜感激

是否可以在从管道执行的bash脚本中获取用户输入?

例如:

wget -q -O - http://myscript.sh | bash
在剧本中:

read -p "Do some action (y/n): " __response
if [[ "$__response" =~ ^[Yy]$ ]]; then
   echo "Performing some action ..."
fi
据我所知,这不起作用,因为read试图从stdin读取输入,而bash脚本目前正在“通过该管道执行”(我确信有一种更精确的技术方法来描述正在发生的事情,但我不知道如何)

我找到了一个建议使用以下方法的解决方案:

read -t 1 __response </dev/tty

read-t1\u响应tty
。使用以下代码进行测试,例如:

$ date | { read -p "Echo date? " r </dev/tty ; [ "$r" = "y" ] && cat || echo OK ; }
Echo date? y
Sat Apr 12 10:51:16 PDT 2014
$ date | { read -p "Echo date? " r </dev/tty ; [ "$r" = "y" ] && cat || echo OK ; }
Echo date? n
OK

首先,选项
-t1
给予
read
一秒钟的超时时间。其次,此命令不提供提示。这两种情况的结合可能意味着,即使是
read
短暂地请求输入,您也不知道。

这不起作用的主要原因是,正如OP有效地指出的

  • 使用的
    |
    将第一个命令的标准输出作为标准输入发送到第二个命令。在本例中,第一个命令是

    wget -q -O - http://myscript.sh
    
    它通过管道将下载的脚本传递给其解释器
    bash

  • 脚本中的
    read
    语句使用相同的标准输入来获取其值

这就是它崩溃的地方,因为
read
并没有等待您的输入,而是从它自己的脚本中获取它。例如:

$ cat - <<EOF | bash 
> set -x
> read p
> somecommand
> echo \$p
> EOF
+ read p
+ echo somecommand
somecommand

这也适用于
zsh
csh
tcsh
ksh
sh
,可能还有很多其他的。

谢谢。工作完美。
$ cat - <<EOF | bash 
> set -x
> read p
> somecommand
> echo \$p
> EOF
+ read p
+ echo somecommand
somecommand
$ bash -c "$(command you want to pipe)"