为何内置命令read在zsh与bash中表现不同?
为什么
read在zsh和bash中通过管道执行的结果不一样? 先来看实际的执行差异:
zsh中的正常表现
在zsh里执行这条命令,完全符合预期:
zsh$ echo Hello | read str ; echo "str is: "$str str is: Hello
bash中的异常表现
但换到bash里跑一模一样的命令,变量str却拿不到值:
bash$ echo Hello | read str ; echo "str is: "$str str is:
核心原因:子shell的处理逻辑差异
问题的关键在于两个shell对管道命令的子shell创建规则不一样:
- 在bash中,管道链里的每一个命令都会被放到独立的子shell中运行。
read str在子shell里完成了变量赋值,但这个变量只存在于子shell的环境里,当子shell结束后,父shell(也就是你当前的会话)根本访问不到这个变量,所以后面的echo输出的是空值。 - 而zsh默认情况下,不会给管道的最后一个命令创建子shell——
read str是在当前shell环境中执行的,变量str直接存在于当前会话里,后面的echo自然能正常读取到它的值。
给bash的替代解决方案
如果想在bash里实现类似zsh的效果,可以避开管道的子shell问题,比如用here-string:
read str <<< "Hello" ; echo "str is: "$str
或者用进程替换配合while循环:
while read str; do echo "str is: "$str; done < <(echo Hello)
内容的提问来源于stack exchange,提问作者mohitmun
相关产品推荐
相关产品推荐

