流程输出到sh while循环?

时间:2014-11-13 15:42:15

标签: while-loop sh

我试图在while循环内逐行循环Perl进程的输出。但是,我在语法方面遇到了困难。

我尝试了这个,但得到了一个"模棱两可的重定向"错误:

#!/bin/sh

while read line; do 
    echo "$line" 
    # do stuff with $line 
done < $(perl process.pl)

./script.sh : line 6: $(perl process.pl): ambiguous redirect

例如,一个(低效)解决方案是:

#!/bin/sh

tmpFile=/tmp/tmpFile.txt
perl process.pl > $tmpFile 
while read line; do 
    echo "$line" 
    # do stuff with $line 
done < $tmpFile

我知道我可以将Perl进程传递给while循环:

perl process.pl | while ...

但是while循环是在子shell中执行的,我需要在循环结束后保留​​while循环中设置的一些变量,所以这不是一个选项。

我该怎么办?

3 个答案:

答案 0 :(得分:2)

你几乎就在那里。试试这个:

while read -r line; do 
    echo "$line" 
    # do stuff with $line 
done < <(perl process.pl)

唯一的区别是<而不是$

$(cmd)是一个命令替换,它扩展为括号内命令的输出。另一方面,<(cmd)process substitution。请注意,这是一个Bash扩展名,因此如果您想使用此方法,还应将shebang更改为#!/bin/bash

或者,如果您不使用Bash,则只需使用管道:

perl process.pl | while read -r line; do 
    echo "$line" 
    # do stuff with $line 
done

除此之外,you almost always want to use the -r switch with read

答案 1 :(得分:2)

使用命名管道; bash进程替换本质上就是语法糖。

mkfifo output
perl process.pl > output &
while IFS= read -r line; do 
    echo "$line" 
    # do stuff with $line 
done < output
rm output

process.pl循环开始消耗输出之前,命名管道不需要while完成。

答案 2 :(得分:1)

使用here-document

while IFS= read -r line; do
    echo "$line" 
    # do stuff with $line 
done <<EOF
$(perl process.pl)
EOF