我有样例脚本:
#!/bin/sh
while read ll </dev/fd/4; do
echo "1 "$ll
while read line; do
echo $line
read input </dev/fd/3
echo "$input"
done 3<&0 <notify-finished
done 4<output_file
当前第一个循环不迭代只停留在第一行。我如何在不出错的情况下修复它,因为它必须是高度可移植的。谢谢。
你的代码已经有 bashisms了。在这里,我把它们拿出来(并简化FD处理以获得更好的可读性):
#!/bin/sh
while read ll <&4; do # read from output_file
printf '%sn' "1 $ll"
while read line <&3; do # read from notify-finished
printf '%sn' "$line"
read input # read from stdin
printf '%sn' "$input"
done 3<notify-finished
done 4<output_file
运行如下脚本:
echo "output_file" >output_file
echo "notify-finished" >notify-finished
echo "stdout" | ./yourscript
…它正确退出,输出如下:
1 output_file
notify-finished
stdout
指出:
-
echo
的行为在POSIX平台上是不可移植的。请参阅POSIX规范中echo
的应用用法部分,其中建议使用printf
。 -
/dev/fd/##
未被POSIX指定;它是Linux发行版(创建一个指向/proc/self/fd
的符号链接——/proc
本身是一个未指定的扩展)和bash本身都可以使用的扩展。使用<&4
代替</dev/fd/4
。 - 您可能希望将
-r
参数用于read
—这是posix指定的,并防止将反斜杠视为IFS中换行符和字符的转义序列的默认行为。如果没有它,foobar
将被读取为foobar
,因此不会读取您的数据,因为它真正存在于其输入源中。