在交互式 shell 中,为什么有人会将 IFS 设置为默认值以外的值?

hel*_*hod 3 shell bash

有时在编写脚本时,可能需要将IFS(内部字段分隔符)设置为默认值以外的其他内容,例如更改$*将扩展的方式。

虽然这完全有道理,但我想不出有任何理由IFS在交互式 shell 中设置除默认值之外的任何内容(如果我没记错的话,它是空格、制表符和换行符)。我仍然经常被告知,在交互式 shell 上,我不能期望IFS将其设置为默认值。

这是真的吗?谁能举个实际的例子?

Sté*_*las 7

在交互式 shell 中,$IFS将是默认值,除非您更改它或在 shell 启动脚本(如~/.bashrcfor bash)或任何其他源脚本或 shell 启动后执行的 shell 函数中更改它(他们通常不会或会更改它)如果它们写得正确,则为默认值)。

如果rc文件或其他文件中定义的那些函数编写正确,并且它们需要使用分词,则它们不会对 IFS 的当前值进行任何假设,因此将其设置为不同的值应该没问题。

然而,一旦你改变它,你必须记住你所做的,因为这可能会影响你稍后运行的命令行的解释方式。

例如,如果你这样做:

IFS=:; ls -- $PATH
Run Code Online (Sandbox Code Playgroud)

要列出 中的目录$PATH,您可能想知道为什么稍后会出现以下内容:

rm -f -- $(cat ~/my.file.list)
Run Code Online (Sandbox Code Playgroud)

不要再工作了。所以你不妨这样写:

(IFS=:; ls -- $PATH)
Run Code Online (Sandbox Code Playgroud)

或者:

IFS=:; ls -- $PATH; unset IFS
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,unset IFS将单词拆分恢复为其默认行为,但不会$IFS并且它破坏了(未正确编写的)执行诸如oldIFS=$IFS; IFS=xxx; ...; IFS=$oldIFS恢复之类的功能$IFS)。

  • @jordanm,不。将 `IFS=:` 插入传递给 `ls` 的环境中(它没有用),但不影响 `$PATH` 在此命令行中的拆分方式。您可以执行`IFS=: command eval 'ls -- $PATH'`,但这有点麻烦。 (3认同)