如何使回声与bash中的读取兼容?

时间:2015-04-13 12:50:53

标签: linux bash command-line pipe echo

我试过了:

qs@BF:~$ echo aaa | read c
qs@BF:~$ echo $c

它什么都没有,这意味着$ c是一个空的宏。

但为什么下面这个有效:

qs@BF:~$ cat trim.hs | read cc
qs@BF:~$ echo $cc
import qualified Data.Text as T

它正确地给出了trim.hs的第一行

echo使用read进行管道传输时,接缝会成为例外情况。 我对吗?你能帮助我echoread兼容吗?请。

2 个答案:

答案 0 :(得分:3)

这些"工作"

都没有
echo aaa | read c
cat trim.hs | read cc

在bash中,管道中的命令都在子shell中执行。因此,read命令在子shell中设置变量c ,但随后子shell退出并且其环境消失

为了演示,让我们使用分组结构在子shell中查询$c的值:

unset c
echo 123 | { read c; echo in subshell: ">$c<"; }
echo in parent: ">$c<"

输出

in subshell: >123<
in parent: ><

bash确实有一个设置允许管道中的 last 命令在当前 shell中运行:

set +m               # job control must be disabled
shopt -s lastpipe    # enable the option
unset d
echo 456 | read d
echo ">$d<"
>456<

答案 1 :(得分:2)

我认为这里的根本问题是运行read的子shell。这些不会(总是)将值传播到您的调用。

POSIX read standard开始,概述了调用方无法看到在子广告单元中使用read的方式:

  

如果在子shell或单独的实用程序执行环境中调用它,例如以下之一:

(read foo)
nohup read ...
find . -exec read ... \;
     

它不会影响调用者环境中的shell变量。

并注意到these shell tips

  

POSIX允许管道中的任何或所有命令在子shell中运行,并且主shell中运行的命令(如果有的话)在实现之间变化很大 - 特别是Bash和ksh在这里不同。克服这个问题的标准习惯是使用这里的文件:

IFS= read var << EOF
$(foo)
EOF