我编写了一个简短的 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
开头之外的 -value。
结论
评论是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
。