打印 IFS 字符
Printing the IFS chars
我注意到要在 shell 中打印 $IFS
变量的值,我必须执行以下操作:
$ printf '%s\nYour IFS is: %q' 'Hello' "$IFS"
Hello
Your IFS is: $' \t\n'
我的问题是为什么我需要以这种特殊方式通过 IFS
?例如,为什么(或为什么不能)可以这样做:
$ echo $IFS
-- 一些打印特殊字符的参数?
$ printf "$IFS"
或 $ printf '$IFS'
-- 为什么它们都不起作用?
- 为什么
$ printf "%q" $IFS
和 $ printf "%q" '$IFS'
没有正确显示但 $ printf "%q" "$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?
- 第一个像
echo
一样对字符串进行插值并按原样打印 IFS
字符串 - 默认情况下是一堆空格。
- 第二个不做插值,明显打印
$IFS
.
printf "%q" $IFS
该变量已经扩展为被 shell 吃掉的空格,因此没有任何内容作为第二个参数传递给 printf
,因此 %q
没有可用的输入与.
printf "%q" '$IFS'
字符串 $IFS
作为参数传递给 %q
,后者只是向其添加转义字符。
您 运行 陷入三个基本问题:
未引用的变量引用(如 echo $IFS
和 printf "%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 字符转换为可见、可读的表示形式。
我注意到要在 shell 中打印 $IFS
变量的值,我必须执行以下操作:
$ printf '%s\nYour IFS is: %q' 'Hello' "$IFS"
Hello
Your IFS is: $' \t\n'
我的问题是为什么我需要以这种特殊方式通过 IFS
?例如,为什么(或为什么不能)可以这样做:
$ echo $IFS
-- 一些打印特殊字符的参数?$ printf "$IFS"
或$ printf '$IFS'
-- 为什么它们都不起作用?- 为什么
$ printf "%q" $IFS
和$ printf "%q" '$IFS'
没有正确显示但$ printf "%q" "$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?
- 第一个像
echo
一样对字符串进行插值并按原样打印IFS
字符串 - 默认情况下是一堆空格。 - 第二个不做插值,明显打印
$IFS
.
printf "%q" $IFS
该变量已经扩展为被 shell 吃掉的空格,因此没有任何内容作为第二个参数传递给 printf
,因此 %q
没有可用的输入与.
printf "%q" '$IFS'
字符串 $IFS
作为参数传递给 %q
,后者只是向其添加转义字符。
您 运行 陷入三个基本问题:
未引用的变量引用(如
echo $IFS
和printf "%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 字符转换为可见、可读的表示形式。