为什么 IFS 会影响子 shell 变量?

Why IFS impact subshell variable?

此 KSH 代码在具有标准 IFS(默认)的 AIX 和 RH 上运行良好

[ "$(uname)" = "AIX" ] && ECHO="echo" || ECHO="echo -e"
echo "AA BB CC DD" | while read a b c d; do
[ "`$ECHO $a | cut -c1-2`" = "AA" ] && echo $b
done

如果我设置不同的 IFS,例如;例如

[ "$(uname)" = "AIX" ] && ECHO="echo" || ECHO="echo -e"
IFS=";"
echo "AA;BB;CC;DD" | while read a b c d; do
[ "`$ECHO $a | cut -c1-2`" = "AA" ] && echo $b
done

我只在 RH 而不是 Aix 上收到错误消息

+ echo 'AA;BB;CC;DD'
+ read a b c d
+ cut -c1-2
+ 'echo -e' AA
-ksh: line 3: echo -e: not found
+ [ '' '=' AA ]
+ read a b c d
+ echo .....
+ cut -d. -f1

有人可以向我解释为什么会这样,以及我们如何在没有 eval 的情况下解决它? 感谢您的宝贵时间:-)

你有 ECHO="echo -e",然后你设置 IFS=";",所以当你扩展 $ECHO 不加引号(globbing 和分词将生效)时,你会得到 echo -e 作为一个单一的word(因为你是用分号而不是空格来分词),当然没有这样的命令。

您需要参考 I'm trying to put a command in a variable, but the complex cases always fail。答案是使用数组:

[ "$(uname)" = "AIX" ] && ECHO=(echo) || ECHO=(echo -e)

然后,像

一样使用它
"${ECHO[@]}" "$a" | cut -c1-2

您还需要更多地使用引号。参考Security implications of forgetting to quote a variable in bash/POSIX shells

(待办事项:讨论不使用 "echo -e"...)