Bash printf 格式化不起作用

tes*_*ter 2 bash printf

例如,\c格式不起作用。我正在输入printf "ABC\ctest"bash 控制台和结果;

ABC\ctest
Run Code Online (Sandbox Code Playgroud)

考虑到\c格式的属性,预期的输出应该是 just 的形式ABC

我也没有找到详细说明在 bash 上使用 printf 命令的正确来源。此外,如上例所示,为 printf 命令指定的手册页上的属性无法正常工作。

请向我展示详细解释 printf 命令的 bash 源代码。因为我现在很迷茫。

Jde*_*eBP 9

printf 'ABC\ctest'

您遇到了printf命令的未指定部分之一,其行为因实现而异。你把 放在\c错误的地方。

如果你读单一Unix规格的的说明printf仔细,你会看到,\c是不是在那些格式字符串(第一个参数的命令)定义的转义序列列表中列出。相反,它被定义为一个额外的转义序列,当%b格式说明符格式化的参数字符串中给出时,该序列被识别。

换句话说:

  • printf '%b\n' 'ABC\ctest'有明确规定的行为。这\c会导致剩余的所有内容(包括格式字符串中的换行符)被忽略。
  • printf '%s\n' 'ABC\ctest'有明确规定的行为。这\c首先不是转义序列。
  • printf '\c'没有明确规定的行为。该SUS是在什么只是无声\c的,而不是将其列为一个转义序列,但也不能说其文件格式符号部分,这样的序列是从来没有一个转义序列。

不同的 shell 响应这种不一致的格式字符串的行为差异很大。以下是 Debian Almquist、Bourne Again、FreeBSD Almquist、Korn '93 和 Z shells 的反应(%s 表示没有换行的地方):

% dash -c "p​​rintf 'ABC\ctest\n'"
ABC\ctest
% bash -c "p​​rintf 'ABC\ctest\n'"
ABC\ctest
% sh -c "p​​rintf 'ABC\ctest\n'"
ABC%
% ksh93 -c "p​​rintf 'ABC\ctest\n'"
ABCest
% zsh -c "p​​rintf 'ABC\ctest\n'"
ABC%
%

我所拥有的 MirBSD Korn 和 PD Korn shell 的printf构建没有内置命令。非内置的 FreeBSDprintf执行以下操作:

% /usr/bin/printf 'ABC\ctest\n'
ABC%
%

更有趣的是,各种 shell 的 doco 有时非常具有误导性,有时甚至是彻头彻尾的错误。举些例子:

  • Z shell doco最近才开始给出正确的描述\c,并将其(通过其 doco for echo)列为格式字符串中允许的转义序列。(直到 2017 年才出错,doco 既不同意SUS也不描述 Z shell 实际做了什么。)
  • Korn '93 shell doco 给出了与SUS一致的描述,但它不是(如上文所述)它\c在格式说明符中实际执行的操作。它也记录\c为格式字符串的转义序列。它的行为显然是一个错误。
  • 对于Bourne Again Shell的的DOCO给Debian Almquist外壳DOCO给出的描述\c是,相匹配SUS和明确有关列出它%b(在伯恩再次壳的更清楚比现在的情况了到2016年)和不在printf格式说明符的转义序列的一般列表中。这些外壳不提供此作为标准的扩展。
  • FreeBSD Almquist shell doco 遵循FreeBSD 外部printf命令手册,其描述\cSUS 一致。它明确将其列为格式字符串中允许的转义序列,其实际行为如用户手册中所述。

FreeBSD Almquist shell 和(最近的)Z shell 是这里唯一的 shell,它们都允许\c作为格式字符串中的转义序列(标准定义的扩展)并且实际上按照它们记录的方式运行。

具有讽刺意味的进一步阅读


Pau*_*omé 5

有必要在相应的参数中扩展反斜杠转义序列。正如指出这里

\c  Terminate output similarly to the \c escape used by echo -e. printf produces no additional output after coming across a \c escape in a %b argument.
Run Code Online (Sandbox Code Playgroud)
\c  Terminate output similarly to the \c escape used by echo -e. printf produces no additional output after coming across a \c escape in a %b argument.
Run Code Online (Sandbox Code Playgroud)