Я написал короткий скрипт оболочки, который просто представляет собой 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. В маловероятном случае, если это имеет значение, я запускаю ZFS On Linux 0.6.3 (то же самое поведение наблюдалось и с 0.6.2) на стандартном ядре Wheezy.
решение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
и там, среди прочего, упоминается:
Относительно варианта-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
. .