打印 IFS 字符

Printing the IFS chars

我注意到要在 shell 中打印 $IFS 变量的值,我必须执行以下操作:

$ printf '%s\nYour IFS is: %q' 'Hello' "$IFS"
Hello
Your IFS is: $' \t\n'

我的问题是为什么我需要以这种特殊方式通过 IFS?例如,为什么(或为什么不能)可以这样做:

如果不引用变量,word-splitting在变量展开后完成。分词将IFS中的所有字符作为分词分隔符;单词之间的一行中的多个单词被折叠成一个 space,如果输出完全是定界符,则什么也不会输出。

您需要在变量周围使用引号才能按字面意义输出它。

然后你需要使用%q格式运算符将其输出为转义序列,这样你就可以看到各个字符是什么。否则你无法分辨出第二个字符是 TAB,你只会在屏幕上看到一堆 space。换行符只会转到下一行。

  • $ echo $IFS -- some parameter that prints special characters?

echo没有这样的参数

  • $ printf "$IFS" or $ printf '$IFS' -- why wouldn't either of these work?
  1. 第一个像 echo 一样对字符串进行插值并按原样打印 IFS 字符串 - 默认情况下是一堆空格。
  2. 第二个不做插值,明显打印$IFS.
  • printf "%q" $IFS

该变量已经扩展为被 shell 吃掉的空格,因此没有任何内容作为第二个参数传递给 printf,因此 %q 没有可用的输入与.

  • printf "%q" '$IFS'

字符串 $IFS 作为参数传递给 %q,后者只是向其添加转义字符。

您 运行 陷入三个基本问题:

  • 未引用的变量引用(如 echo $IFSprintf "%q" $IFS)进行分词。基本上,变量值中的任何 whitespace 都被视为“单词”(作为参数传递给命令)之间的分隔符。但是“whitespace”被定义为 $IFS 中的字符(这就是它的用途!)。因此,整个变量的值仅被视为间距,而不是实际内容,并且实际上消失了!

    这是为什么您应该 double-quotes 围绕变量引用的众多示例之一。

  • Single-quoted 字符串(如 printf '$IFS'printf "%q" '$IFS')根本不进行变量扩展。在这些情况下,$IFS 只是一个文字字符串,而不是变量引用。

  • 最后,$IFS 中的默认字符在屏幕上不是特别明显。 printf "$IFS" 实际上确实正确打印了它们(除非出于某种原因在 IFS 中放置了“%”或“\”),但您无法真正看到它们。默认情况下,$IFS 中的第一个字符是 space,因此当打印时光标移动到第二列,但没有显示任何内容。第二个字符是制表符,因此光标移动得更远,但实际上什么也看不到。然后最后一个字符是一个换行符,所以光标移动到下一行的开头......同样,没有任何可见的东西出现。

    这就是为什么需要 printf %q -- %q 格式将 $IFS 中的 not-really-visible 字符转换为可见、可读的表示形式。