É muito difícil lidar com zero bytes do bash. Você pode produzir um byte zero por
printf %c
mas você não pode armazená-lo em uma variável.
É muito mais fácil usar ferramentas externas:
xxd < mydata.bin > encoded
xxd -r < encoded > binary
Eu quero criar um script bash que leia uma "carga útil" de dados binários de um arquivo externo e cuspa outro script básico com esses dados escapados e encapsulados dentro de uma variável de string. Exemplo:
Para usar isso eu rodaria myscript.sh mydata.bin mypayload.sh
e myscript.sh converteria / escape / wrap / qualquer que fosse o arquivo mydata.bin para mypayload.sh
Depois de executar este comando, o arquivo mypayload.sh
seria algo como isto:
# Generated by myencoder.sh with data from mydata.bin
encoded_data="[...]ugly escaped string representation of the binary data found in mydata.bin[...]"
O problema que estou enfrentando é a maneira de resolver como os dados seriam codificados adequadamente. Eu li que printf "% q" poderia ser usado para escapar seqüências de caracteres, mas como invocá-lo em dados obtidos a partir de um arquivo binário externo me escapou completamente.
Então, por favor, qualquer facada neste e quaisquer dicas são bem vindas!
PS: Eu não quero introduzir nenhuma dependência fora do bash, se possível. Dependendo dos recursos do bash 4.x, tudo bem.
PPS: A codificação deve favorecer o tamanho pequeno e o desempenho de codificação / decodificação.
É muito difícil lidar com zero bytes do bash. Você pode produzir um byte zero por
printf %c
mas você não pode armazená-lo em uma variável.
É muito mais fácil usar ferramentas externas:
xxd < mydata.bin > encoded
xxd -r < encoded > binary
Esta não é uma solução completa para o seu problema; como outros mencionaram, lidar com NULLs em seu arquivo de entrada é difícil no bash, e tenho certeza que o potencial de arquivos de entrada unicode pode causar ainda mais dores de cabeça.
Mas eu dedico um pouco de tempo para pensar em como você pode usar printf %q
no bash para fazer algo semelhante à sua sugestão e criou este rápido truque:
echo -n 'myvar="'
while read -r; do
if [ ! -z "$REPLY" ]; then
printf %q "$REPLY"
fi
echo -n '\n'
done
echo '"'
Tenho certeza de que poderia quebrar de muitas maneiras, mas talvez isso satisfaça alguma parte de sua curiosidade.
Esta resposta não responde a pergunta diretamente, porque aparentemente conter 0 bytes nas variáveis bash não é possível e, aparentemente, não há como escapar delas em strings que podem ser mantidas com segurança dentro de variáveis bash sem depender de ferramentas externas como xxd ou uuencode que não estão disponíveis por padrão nas plataformas onde meu script será executado.
No entanto, esta foi a solução que acabei procurando porque resolveu meu problema mais próximo, ou seja, criar um script que contém dados binários arbitrários como uma carga útil que pode ser manipulada pelo próprio script que a contém.
Eu usei este artigo como minha fonte. Basicamente, a abordagem usa uma string separadora entre o script e os dados binários e nunca permite que o intérprete bash atinja a parte binária no final.