Eu escrevi um pequeno script de shell que simplesmente envolve setfattr
uma forma um pouco mais conveniente para definir o atributo estendido que corresponde a um comentário de texto livre:
#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -d -m '^user.xdg.comment$' "$1"
Para armazenar comentários ASCII dos EUA como xattrs, isso funciona muito bem. No entanto, se eu tentar definir um comentário que contenha caracteres não ASCII dos EUA, ele retornará o que parecem ser dados codificados em Base64:
$ touch xyz
$ set-comment xyz åäöåä
# file: xyz
user.xdg.comment=0sw6XDpMO2w6XDpA==
$
Mas não é apenas Base64:
$ printf "0sw6XDpMO2w6XDpA==" | \base64 --decode
��:\:L;l:\:@base64: invalid input
$
Na maioria das vezes, eu receboapenaslixo de aparência aleatória de volta. Algumas vezes, assim, o decodificador Base64 lança "entrada inválida" de volta para mim.
O que é essa sequência?Qual é a sua relação com o valor de entrada original? Como faço para passar do que getfattr
me devolve ao valor de entrada original (como åäöåä
neste caso)?
setfattr --version
no meu sistema responde com setfattr 2.4.46
. Estou executando a versão empacotada pelo Debian Wheezy. No caso improvável de que isso importe, estou executando o ZFS no Linux 0.6.3 (também vi o mesmo comportamento com o 0.6.2) no kernel Wheezy padrão.
Responder1
Fiquei um pouco curioso lendo esta pergunta, então vamos fazer algumas"forense":
Primeiro tentando o oposto:
Como é åäöåä
codificado em Base64?
$ echo åäöåä | base64
w6XDpMO2w6XDpAo=
Isso claramente se parece muito com o 0sw6XDpMO2w6XDpA==
que você tem. Há um extra 0s
no início e o final não corresponde exatamente. Suprimindo a nova linha no final de åäöåä
(inserida automaticamente por echo
), obtemos:
$ echo -n åäöåä | base64
w6XDpMO2w6XDpA==
Este é exatamente o user.xdg.comment
valor, exceto 0s
no início.
Conclusão
O comentárioéCodificado em Base64 e prefixado com 0s
, e testar algumas outras strings confirma isso.
Exemplo:
$ ./set-comment xyz 日本語
# file: xyz
user.xdg.comment=0s5pel5pys6Kqe
$ base64 -d <<<'5pel5pys6Kqe' ; echo
日本語
(onde ; echo
é para não atrapalhar o próximo prompt, pois a saída de base64
não termina em uma nova linha.)
No entanto...
Isso apenas mostra que nesses casos (onde o comentário não é ASCII), ele é codificado em Base64 e prefixado com 0s
.
A resposta “real”
Depois de fazer isso, tive a esplêndida ideia de verificar a página de manual getfattr
e ela menciona, entre outras coisas:
Em relação à opção-e en, --encoding=en
Codifique os valores após recuperá-los. Os valores válidos de en são "texto", "hex" e "base64". Os valores codificados como strings de texto são colocados entre aspas duplas ("), enquanto as strings codificadas como hexadecimal e base64 são prefixadas com 0x e 0s, respectivamente.
Então, alterando seu script para:
(Arquivodefinir comentário:)
#!/bin/sh
test "$2" && setfattr -n user.xdg.comment -v "$2" "$1"
getfattr -e text -d -m '^user.xdg.comment$' "$1"
sempre imprimirá o atributo como texto, dando, por exemplo:
$ ./set-comment xyz åäöåä # with fixed script
# file: xyz
user.xdg.comment="åäöåä"
No entanto, ainda restam algumas ressalvas... como:
$ ./set-comment xyz 0x414243
# file: xyz
user.xdg.comment="ABC"
e
$ ./set-comment xyz 0s5pel5pys6Kqe
# file: xyz
user.xdg.comment="日本語"
onde a saída não corresponde à entrada.
Isso pode ser corrigido “massageando” o argumento em uma forma que setfattr
você goste. Ver man setfattr
.