Xattr

setfattr 這個看似 base64 的數據集是什麼?

  • June 23, 2014

我編寫了一個簡短的 shell 腳本,它簡單地包裝setfattr成一種更方便的形式,用於設置與自由文本註釋相對應的擴展屬性:

#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -d -m '^user.xdg.comment$' "$1"

對於將美國 ASCII 註釋儲存為 xattrs,這非常有用。但是,如果我嘗試設置包含非美國 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 核心上執行 Linux 0.6.3 上的 ZFS(也看到了與 0.6.2 相同的行為)。

我讀到這個問題有點好奇,所以讓我們做一些*“取證”*:

首先嘗試相反的:

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其中提到:

關於選項-e en, --encoding=en

檢索值後對其進行編碼。en 的有效值為“text”、“hex”和“base64”。編碼為文本字元串的值用雙引號 (") 括起來,而編碼為十六進制和 base64 的字元串分別以 0x 和 0s 為前綴。

因此,將腳本更改為:

(文件集評論:)

#!/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

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