Shell

使用 printf 命令時需要轉義哪些字元?

  • November 15, 2019

我想澄清一下,我不是在談論如何在 shell 解釋級別上轉義字元。

據我所知,只需要轉義兩個字元:%\

要列印文字%,您必須使用前面的 轉義它%

printf '%%'

要列印文字\,您必須使用前面的 : 對其進行轉義\

printf '\\'

是否有任何其他情況我需要轉義一個字元才能按字面意思解釋它?

在 的格式參數中printf,只有%and\字元是特殊的(不,"不是特殊的,並且\"根據 POSIX 未指定)。

但是,有兩個重要的注意事項。

  1. 在大多數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

最好是避免使用(甚至安裝/提供)這些語言環境,因為它們會導致各種錯誤和此類漏洞。 2. 一些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}.


¹yashprintf內置是我知道的唯一例外。

引用自:https://unix.stackexchange.com/questions/494725