Harold Fischer Asked: 2019-01-16 20:19:55 +0800 CST2019-01-16 20:19:55 +0800 CST 2019-01-16 20:19:55 +0800 CST 使用 printf 命令时需要转义哪些字符? 772 我想澄清一下,我不是在谈论如何在 shell 解释级别上转义字符。 据我所知,只需要转义两个字符:%和\ 要打印文字%,您必须使用前面的 转义它%: printf '%%' 要打印文字\,您必须使用前面的 : 对其进行转义\: printf '\\' 是否有任何其他情况我需要转义一个字符才能按字面意思解释它? shell posix 2 个回答 Voted Best Answer Stéphane Chazelas 2019-11-16T04:02:05+08:002019-11-16T04:02:05+08:00 在 的格式参数中printf,只有%and\字符是特殊的(不,"不是特殊的,并且\"根据 POSIX 未指定)。 但是,有两个重要的注意事项。 在大多数printf实现中¹,它的字节值是特殊的,\并且%POSIX 规范甚至可以解释为需要它,因为它要求printf实用程序是printf(3)C 函数的接口,而不是wprintf(3)例如(就像它需要%.3s截断为 3 个字节而不是 3 个字符)。 在包括 BIG5 和 GB18030 在内的一些字符编码中,有数百个字符包含反斜杠的编码,要转义那些 for printf,您需要在这些字符的编码中的\每个0x5c字节之前插入一个! 例如在 BIG5-HKSCS 中,例如在zh_HK.big5hkscs(香港)语言环境中使用的,都Ěαжふ㘘㙡䓀䨵䪤么佢俞偅傜兝功吒吭园坼垥塿墦声娉娖娫嫹嬞孀尐岤崤幋廄惝愧揊擺暝枯柦槙檝歿汻沔涂淚滜潿瀙瀵焮燡牾狖獦珢珮琵璞疱癧礒稞穀笋箤糭綅縷罡胐胬脪苒茻莍蓋蔌蕚螏螰許豹贕赨跚踊蹾躡鄃酀酅醆鈾鎪閱鞸餐餤駹騱髏髢髿鱋鱭黠﹏?????????包含字节 0x5c(这也是 的编码\)。 对于大多数printf实现,在该语言环境中,printf 'αb'不输出αb字节0xa3(编码的第一个字节α),后跟BS字符(的扩展\b)。 $ LC_ALL=zh_HK.big5hkscs luit $ locale charmap BIG5-HKSCS $ printf 'αb' | LC_ALL=C od -tx1 -tc 0000000 a3 08 243 \b 0000002 最好是避免使用(甚至安装/提供)这些语言环境,因为它们会导致各种错误和此类漏洞。 一些printf实现支持选项,甚至那些不需要支持--作为选项分隔符的实现。因此printf --不会输出--,但可能会报告有关缺少格式参数的错误。因此,如果您不能保证您的格式不会以 开头-,则必须使用--选项分隔符: printf -- "$escaped_format" x y... 在任何情况下,如果你想打印任意字符串,你会使用: printf '%s\n' "$data" # with terminating newline printf %s "$data" # without 在传递给的字符串中没有特殊的字符%s(尽管请注意,除了printf内置的之外zsh,您不能在任何printf参数中传递 NUL 字符)。 请注意,虽然在基于 ASCII 的系统上输入文字的规范方法\是 with\\和文字%with %%,但您也可以将\134and\45与某些printf实现一起使用\x5c, \x25, or \x{5c}, \x{25}, or (甚至在非 ASCII 系统上):\u005c, \u0025or \u{5c}, \u{25}. ¹yash的printf内置是我知道的唯一例外。 Sparhawk 2019-01-16T20:38:36+08:002019-01-16T20:38:36+08:00 从手册: $ man printf ... printf FORMAT [ARGUMENT]... ... FORMAT controls the output as in C printf. Interpreted sequences are: 这列出了几个解释序列。以下是字符本身需要转义的地方。 \" double quote \\ backslash %% a single % 我在 中测试了这三个bash,它们的行为符合预期。根据man bash,此实现printf使用上述“标准 printf(1) 格式规范”,此外还有一些与此处无关的内容。 但是,其他外壳(例如)的zsh实现方式printf略有不同。在这里,不应转义双引号。 $ printf '"' " $ printf '\"' \"
在 的格式参数中
printf
,只有%
and\
字符是特殊的(不,"
不是特殊的,并且\"
根据 POSIX 未指定)。但是,有两个重要的注意事项。
在大多数
printf
实现中¹,它的字节值是特殊的,\
并且%
POSIX 规范甚至可以解释为需要它,因为它要求printf
实用程序是printf(3)
C 函数的接口,而不是wprintf(3)
例如(就像它需要%.3s
截断为 3 个字节而不是 3 个字符)。在包括 BIG5 和 GB18030 在内的一些字符编码中,有数百个字符包含反斜杠的编码,要转义那些 for
printf
,您需要在这些字符的编码中的\
每个0x5c
字节之前插入一个!例如在 BIG5-HKSCS 中,例如在
zh_HK.big5hkscs
(香港)语言环境中使用的,都Ěαжふ㘘㙡䓀䨵䪤么佢俞偅傜兝功吒吭园坼垥塿墦声娉娖娫嫹嬞孀尐岤崤幋廄惝愧揊擺暝枯柦槙檝歿汻沔涂淚滜潿瀙瀵焮燡牾狖獦珢珮琵璞疱癧礒稞穀笋箤糭綅縷罡胐胬脪苒茻莍蓋蔌蕚螏螰許豹贕赨跚踊蹾躡鄃酀酅醆鈾鎪閱鞸餐餤駹騱髏髢髿鱋鱭黠﹏?????????
包含字节 0x5c(这也是 的编码\
)。对于大多数
printf
实现,在该语言环境中,printf 'αb'
不输出αb
字节0xa3
(编码的第一个字节α
),后跟BS字符(的扩展\b
)。最好是避免使用(甚至安装/提供)这些语言环境,因为它们会导致各种错误和此类漏洞。
一些
printf
实现支持选项,甚至那些不需要支持--
作为选项分隔符的实现。因此printf --
不会输出--
,但可能会报告有关缺少格式参数的错误。因此,如果您不能保证您的格式不会以 开头-
,则必须使用--
选项分隔符:在任何情况下,如果你想打印任意字符串,你会使用:
在传递给的字符串中没有特殊的字符
%s
(尽管请注意,除了printf
内置的之外zsh
,您不能在任何printf
参数中传递 NUL 字符)。请注意,虽然在基于 ASCII 的系统上输入文字的规范方法
\
是 with\\
和文字%
with%%
,但您也可以将\134
and\45
与某些printf
实现一起使用\x5c
,\x25
, or\x{5c}
,\x{25}
, or (甚至在非 ASCII 系统上):\u005c
,\u0025
or\u{5c}
,\u{25}
.¹
yash
的printf
内置是我知道的唯一例外。从手册:
这列出了几个解释序列。以下是字符本身需要转义的地方。
我在 中测试了这三个
bash
,它们的行为符合预期。根据man bash
,此实现printf
使用上述“标准 printf(1) 格式规范”,此外还有一些与此处无关的内容。但是,其他外壳(例如)的
zsh
实现方式printf
略有不同。在这里,不应转义双引号。