因为我爱上了它,所以我想写个便条。我找到了这个线程,因为我必须重写一个旧的sh脚本才能与POSIX兼容。这基本上意味着通过重写如下代码来避免POSIX引入的管道/子外壳问题:
some_command | read a b c
变成:
read a b c << EOF
$(some_command)
EOF
像这样的代码:
some_command |
while read a b c; do
# something
done
变成:
while read a b c; do
# something
done << EOF
$(some_command)
EOF
但是后者在空输入时的行为并不相同。使用旧的表示法时,while循环不会在空输入中输入,但是在POSIX表示法中是!我认为这是由于EOF之前的换行符,不能省略。行为更像旧符号的POSIX代码如下所示:
while read a b c; do
case $a in ("") break; esac
# something
done << EOF
$(some_command)
EOF
在大多数情况下,这应该足够好。但是不幸的是,如果some_command打印一个空行,它的行为仍然与旧记法并不完全一样。在旧的表示法中,while主体被执行,而在POSIX表示法中,我们在主体的前面中断。
解决此问题的方法可能如下所示:
while read a b c; do
case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
# something
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF