因为我被它迷住了,所以我想留个言。
我发现了这个帖子,是因为我必须重写一个旧的sh脚本
以使其符合POSIX标准。
这基本上意味着通过改写像这样的代码来规避由POSIX引入的管道/子shell问题:
some_command | read a b c
into:
read a b c << EOF
$(some_command)
EOF
并且像这样的代码:
some_command |
while read a b c; do
done
into:
while read a b c; do
done << EOF
$(some_command)
EOF
然而,对于空输入,后者的行为并不相同。
使用旧符号表示法时,在空输入上while循环不会进入,
但在POSIX表示法中会进入!
我认为这是由于EOF之前的换行符造成的,
它不能被省略。
行为更像旧符号表示法的POSIX代码如下:
while read a b c; do
case $a in ("") break; esac
done << EOF
$(some_command)
EOF
在大部分情况下这应该足够好了。但遗憾的是,如果一些命令输出空行,则此方法仍然不像旧有的表示法那样准确。在旧有的表示法中,while循环体会被执行,而在POSIX表示法中,我们会在循环体前跳出。
解决这个问题的方法可能如下:
while read a b c; do
case $a in ("something_guaranteed_not_to_be_printed_by_some_command") break; esac
done << EOF
$(some_command)
echo "something_guaranteed_not_to_be_printed_by_some_command"
EOF
shopt -s lastpipe
命令,管道中的最后一个命令应该会影响到变量 -- http://tldp.org/LDP/abs/html/bashver4.html#LASTPIPEOPT - imz -- Ivan Zakharyaschev