IFS null 与未设置 IFS 不一样?

tes*_*est 13 shell shell-script bourne-shell

我在这里读了一个很棒的问题,叫做“理解 IFS”。我很惊讶,因为答案和评论引用了 POSIX,它指出 IFS= 与取消 IFS 不同。如果您取消设置 IFS,显然会使用默认值。如果您将 IFS 设为 null,则没有拆分器。我知道我看到了不同的看法,我在我的书签中找到了这个:

Bourne Shell 编程

$IFS

脚本中的第一条语句应该是

IFS=

它将输入字段分隔符重置为其默认值。否则,您将从用户那里继承 $IFS,用户可能将它设置为一些奇怪的值,以使 sh 解析字符串的方式与您期望的方式不同,并导致奇怪的行为。

那么前一段时间是真的还是作者错了?

Gil*_*il' 21

您在 Stack Exchange 上找到的答案是正确的,而本教程是错误的。您可以自己试验或在标准中查找。unsetIFS相当于将其设置为 space-tab-newline 的默认值,而 emptyIFS有效地关闭了字段拆分。

您可以在 IFS 上查阅Sven Mascheck关于历史实现的页面。一些历史 shell 不喜欢unset IFS,一个非常旧版本的 ksh 将它视为一个空的,IFS但所有现代 shell 和大多数旧 shell 将 unset 视为IFS默认值。

你不应该开始你的脚本,IFS=除非你想关闭字段分割(这可能是一个合理的决定——但请注意,你仍然需要在替换周围加上双引号以避免通配,除非你也关闭它set -f)。要重置默认值,请使用unset IFS。这在脚本的开头是否有用是有争议的。还有很多其他不好的事情,例如PATH调用者可以做的狡猾使您的脚本出错。

本教程还建议重置PATH. 这通常是不好的建议。在大多数情况下,您无法预测正确的搜索路径是什么,但用户知道。您如何知道在古老的 unix 上是否/usr/local/bin/home/bob/bin包含修复了错误的实用程序版本,其中的那些/usr/bin有错误?你真的想嵌入所有的逻辑来弄清楚是否要/usr/xpg6/bin提前/bin?你想在什么位置/usr/gnu/bin?除非您的脚本针对特定系统,否则不要重置 PATH。

我没有读过这个教程,但我确实检查了一件事情:它并没有从一开始就告诉你总是在变量替换和命令替换周围加上双引号。所以我不认为这个教程是好的。