如何在Bash中使用读命令?

当我尝试在Bash中使用read命令时:

 echo hello | read str echo $str 

没有任何回应,而我认为str应该包含stringhello 。 任何人都可以帮我理解这种行为吗?

read你的脚本命令是好的。 但是,您在pipe道中执行它,这意味着它在一个子shell中,因此它读取的variables在父shell中不可见。 你也可以

  • 在子shell中移动脚本的其余部分:

     echo hello | { read str echo $str } 
  • 或者使用命令replace从subhell中获取variables的值

     str=$(echo hello) echo $str 

    或者稍微复杂一些的例子(抓住ls的第二个元素)

     str=$(ls | { read a; read a; echo $a; }) echo $str 

其他不涉及子shell的bash替代方法:

 read str <<END # here-doc hello END read str <<< "hello" # here-string read str < <(echo hello) # process substitution 

典型用法可能如下所示:

 i=0 echo -e "hello1\nhello2\nhello3" | while read str ; do echo "$((++i)): $str" done 

并输出

 1: hello1 2: hello2 3: hello3 

由于读命令在单独的子shell中运行,该值将消失: Bash FAQ 24

把我的两分钱放在这里:在KSH上, read一个variables是可行的,因为根据IBM AIX文档 ,KSH的read 确实会影响当前的shell环境:

read命令对shellvariables的设置会影响当前的shell执行环境。

这只是导致我花了好几分钟的时间搞清楚,为什么在AIX上使用了数十亿次的单行结尾并没有在Linux上工作……这是因为KSH确实节省了当前的环境, BASH不!

另一个替代scheme是使用printf函数。

 printf -v str 'hello' 

此外,这个结构,在适当的情况下结合使用单引号,有助于避免subhells和其他forms的内插引用的多逃逸问题。

我真的只用“while”和do循环来读取:

 echo "This is NOT a test." | while read -rabc theRest; do echo "$a" "$b" "$theRest"; done 

这是一个testing。
对于什么是值得的,我已经看到build议总是使用-r与bash中的读取命令。

你需要pipe道吗?

 echo -ne "$MENU" read NUMBER