我遇到了 bash 中一个不幸的错误功能问题,如下面这个功能所示:
trying ()
{
res=0;
echo $res;
cat some_text_file | while read op rpt rec; do
res=1;
echo $res;
done;
echo $res
}
我原本期望最后echo $res
打印的是1
- 但是,它打印的是0
。原因是以 开头的循环cat some_text_file | while read op rpt rec; do
在子 shell 中运行,而在 ksh 中则不会。
对于这个简单案例的解决方法是:
trying ()
{
res=0;
echo $res;
while read op rpt rec; do
res=1;
echo $res;
done < some_text_file;
echo $res
}
然而,在大多数情况下,它更像是cat some_file | awk '{...}' | while read ...
,我真的不想为此创建一个临时文件;它应该可以工作。
不幸的是,我的服务器上使用的是 bash,否则到处都会是 ksh。那么,有什么好方法可以解决这个问题吗?
答案1
有几种解决方法:
您可以激活
shopt -s lastpipe
以获得类似 ksh 的行为。这仅在禁用作业控制的情况下有效 - 即您始终可以在独立脚本中使用此选项,但在使用交互式 shell 时,它只会影响(
子 shell内的管道)
。如果变量只需要短暂存在(并且除了 'while' 循环之外没有任何东西需要读取 stdin),你可以通过管道连接到命令列表:
cat some_file | awk '{...}' | { res=0 echo $res while read op rpt rec; do res=1 echo $res done echo $res }
你可以使用 bash 的流程替代操作符
<(...)
从子 shell 中读取,就像它是一个命名文件一样,包括将其重定向到“while”循环:res=0 echo $res while read op rpt rec; do res=1 echo $res done < <(cat some_file | awk '{...}') echo $res
您已经在使用 awk...
cat some_file | awk '{...}' | awk ' BEGIN { res = 0 } { res = 1 } END { print res } '