Después de usar el siguiente comando,
pngString="$(cat example.png)"
echo -n "$pngString" > tmp.png
No puedo abrir el archivo tmp.png como un archivo PNG. Tal vez se pierde algo de información cuando uso $pngString
para almacenar el archivo de imagen.
Entonces la pregunta es: ¿cómo puedo almacenar la información de imagen completa usando una variable en script bash?
cat
yecho
todo lo demás son utilidades de texto en el fondo . Dejarlos soltar desprevenidos en archivos binarios tendrá resultados impredecibles. Por esobase64
se inventaron cosas como .cat example.png > tmp.png
o mejor aúncp example.png tmp.png
?cat
no es realmente una utilidad de texto. Es la sustitución de comandos (que elimina las nuevas líneas finales), la asignación de variables (que no puede contener bytes nulos) y elecho
comando (que puede interpretar secuencias de barra invertida) lo que destrozará el binario, nocat
. Pero estoy de acuerdo con su punto general.Respuestas:
Tienes razón en eso
echo
y la compañía no parece manejar bien el binario. Sospecho que los caracteres nulos rompen la corriente demasiado pronto.Puede convertir la información de la imagen en algún formato basado en ASCII. Por ejemplo, esto es con
base64
:fuente
echo "$pic" | base64 --decode > pic2.jpeg
El problema es que los bytes nulos no se pueden pasar a través de argumentos de línea de comandos, ya que se usan internamente como terminadores de argumentos. Todos los demás bytes parecen estar bien. Por lo tanto, una alternativa algo más eficiente (típicamente) al uso
base64
sería escapar de los bytes nulos y luego usarprintf
para convertir los datos a la forma original:Los caracteres
\
y%
son especiales, porprintf
lo que también deben escapar.También tenga en cuenta que si los datos de entrada terminan con una nueva línea, se eliminarán mediante la sustitución de comandos. Eso no debería ser un problema específico para PNG ya que el último byte en un PNG válido debe ser 0x82, el byte menos significativo en la
IEND
suma CRC del fragmento vacío .fuente
sed s/\\\\/\\\\\\\\/g\;s/%/%%/g\;s/\\x00/\\\\x00/g