我试图在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
循环中设置的一些变量,所以这不是一个选项。
我该怎么办?
答案 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
答案 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)
while IFS= read -r line; do
echo "$line"
# do stuff with $line
done <<EOF
$(perl process.pl)
EOF