当我尝试在Bash中使用read
命令时:
echo hello | read str
echo $str
没有回音,我认为str
应该包含字符串hello
。有人可以帮我理解这种行为吗?
答案 0 :(得分:56)
脚本命令中的read
没问题。但是,您在管道中执行它,这意味着它在子shell中,因此,它读取的变量在父shell中不可见。你可以
也可以在子shell中移动脚本的其余部分:
echo hello | { read str
echo $str
}
或使用命令替换从子shell中获取变量的值
str=$(echo hello)
echo $str
或稍微复杂的例子(抓住ls的第2个元素)
str=$(ls | { read a; read a; echo $a; })
echo $str
答案 1 :(得分:38)
其他不涉及子shell的bash替代方案:
read str <<END # here-doc
hello
END
read str <<< "hello" # here-string
read str < <(echo hello) # process substitution
答案 2 :(得分:8)
典型用法可能如下:
i=0
echo -e "hello1\nhello2\nhello3" | while read str ; do
echo "$((++i)): $str"
done
和输出
1: hello1
2: hello2
3: hello3
答案 3 :(得分:3)
该值消失,因为read命令在单独的子shell中运行:Bash FAQ 24
答案 4 :(得分:2)
把我的两分钱放在KSH上,read
和变量将一样工作,因为根据the IBM AIX documentation,KSH的read
< em> 影响当前的shell环境:
read命令设置shell变量会影响当前的shell执行环境。
这只是让我花了好几分钟来弄清楚为什么我在AIX上使用了数千次的read
的单行结尾在Linux上无效...这是因为KSH确实保存到当前环境而BASH没有保存!
答案 5 :(得分:0)
我真的只使用&#34;而&#34;和一个循环:
echo "This is NOT a test." | while read -r a b c theRest; do
echo "$a" "$b" "$theRest"; done
这是一个测试 对于它的价值,我已经看到了建议在bash中始终使用-r和read命令。
答案 6 :(得分:-1)
另一种选择是使用printf函数。
printf -v str 'hello'
此外,这种结构与适当时使用单引号相结合,有助于避免子壳和其他形式的插值引用的多逃逸问题。
答案 7 :(得分:-6)
你需要管道吗?
echo -ne "$MENU"
read NUMBER