我編寫了一個簡短的 shell 腳本,它只是以setfattr
稍微更方便的形式包裝,用於設定與自由文字註釋相對應的擴展屬性:
#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -d -m '^user.xdg.comment$' "$1"
對於將 US ASCII 註釋儲存為 xattrs,這非常有效。但是,如果我嘗試設定包含非 US ASCII 字元的註釋,它會傳回看似 Base64 編碼的資料:
$ touch xyz
$ set-comment xyz åäöåä
# file: xyz
user.xdg.comment=0sw6XDpMO2w6XDpA==
$
但它不僅僅是 Base64:
$ printf "0sw6XDpMO2w6XDpA==" | \base64 --decode
��:\:L;l:\:@base64: invalid input
$
大多數時候,我得到只是看起來隨機的垃圾回來了。有時,像這樣,Base64 解碼器會向我傳回「無效輸入」。
這個字串是什麼?它與原始輸入值有什麼關係?我如何從getfattr
給我的值返回到原始輸入值(例如åäöåä
在本例中)?
setfattr --version
在我的系統上響應為setfattr 2.4.46
.我正在運行 Debian Wheezy 打包的版本。萬一重要的是,我在現有的 Wheezy 核心上運行 ZFS On Linux 0.6.3(在 0.6.2 中也看到了相同的行為)。
答案1
我讀這個問題有點好奇,所以讓我們做一些“法醫”:
首先嘗試相反的方法:
åäöåä
Base64是如何編碼的?
$ echo åäöåä | base64
w6XDpMO2w6XDpAo=
這顯然看起來很像0sw6XDpMO2w6XDpA==
你所擁有的。0s
開頭有多餘的內容,結尾卻不太相符。抑制末尾的換行符åäöåä
(由 自動插入echo
),我們得到:
$ echo -n åäöåä | base64
w6XDpMO2w6XDpA==
這正是user.xdg.comment
除0s
開頭處的 - 值之外的值。
結論
評論是Base64 編碼並以 為前綴0s
,並測試其他一些字串證實了這一點。
例子:
$ ./set-comment xyz 日本語
# file: xyz
user.xdg.comment=0s5pel5pys6Kqe
$ base64 -d <<<'5pel5pys6Kqe' ; echo
日本語
(其中 是; echo
為了不弄亂下一個提示,因為 的輸出base64
不會以換行符號結尾。)
然而...
這只是表明,在這些情況下(註釋是非 ASCII),它會以 Base64 進行編碼並以0s
.
「真實」的答案
完成此操作後,我想到了一個絕妙的主意,那就是檢查手冊頁getfattr
,其中提到了以下內容:
關於th選項-e en, --encoding=en
檢索值後對其進行編碼。 en 的有效值為「text」、「hex」和「base64」。編碼為文字字串的值以雙引號 (") 括起來,而編碼為十六進位和 base64 的字串分別以 0x 和 0 為前綴。
因此,將腳本更改為:
(文件設定註釋:)
#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -e text -d -m '^user.xdg.comment$' "$1"
將始終將屬性列印為文本,例如:
$ ./set-comment xyz åäöåä # with fixed script
# file: xyz
user.xdg.comment="åäöåä"
然而,仍然有一些警告......例如:
$ ./set-comment xyz 0x414243
# file: xyz
user.xdg.comment="ABC"
和
$ ./set-comment xyz 0s5pel5pys6Kqe
# file: xyz
user.xdg.comment="日本語"
輸出與輸入不匹配的地方。
這些可以透過將論點「按摩」成setfattr
喜歡的形式來解決。看man setfattr
。