如何在bash变量中存储图像文件?


14

使用以下命令后,

pngString="$(cat example.png)"    
echo -n "$pngString" > tmp.png

我无法将tmp.png作为PNG文件打开。当我$pngString用来存储图像文件时,某些信息可能会丢失。

所以问题是:如何在bash脚本中使用变量存储完整的图像信息?


cat命令可以正常工作(将图像数据存储在变量中)。只需删除双引号即可。问题是将数据保存在变量中后您要如何处理这些数据?
coffeMug ​​2013年

5
cat并且echo其所有功能都是文本实用程序。毫无疑问地让它们在二进制文件上松动将导致无法预料的结果。这就是为什么base64发明类似东西的原因。
Shadur

为什么要将其作为变量?Shell变量通常用于存储少量文本,而不是大量二进制数据。除了zsh之外,任何普通的shell都无法处理变量中的二进制数据(它们扼杀了空字节)。
吉尔(Gilles)'“ SO-别再邪恶了”

为什么不只是cat example.png > tmp.png更好呢cp example.png tmp.png
通配符

@Shadur,cat实际上不是文本实用程序。是命令替换(删除尾随换行符),变量赋值(不能包含空字节)和echo命令(可以解释反斜杠序列),它们将破坏二进制文件,而不是cat。但我同意你的总体观点。
通配符

Answers:


20

您是对的,echo公司似乎不太擅长处理二进制文件。我怀疑空字符会太早中断流。

您可以使用某些基于ASCII的格式转换图片信息。例如,这与base64

$ pic=`base64 pic.jpeg`
$ echo $pic | base64 --decode > pic2.jpeg
$ diff pic*
$ echo $?
0

3
在我的bash系统中,必须将变量括在引号中,可能是因为base64可以包含空格:echo "$pic" | base64 --decode > pic2.jpeg
OldTimer 2013年

1

问题在于空字节不能通过命令行参数传递,因为它们在内部用作参数终止符。所有其他字节似乎都很好。因此,使用某种更具空间效率(通常)的替代方法base64是转义空字节,然后用于printf将数据转换为原始格式:

pngString="$(sed 's/\\/\\\\/g;s/%/%%/g;s/\x00/\\x00/g' <example.png)"
printf "$pngString" >tmp.png

\%字符是特殊的,以printf使他们需要太多逃脱。

另请注意,如果输入数据以换行符结尾,则将通过命令替换将其删除。对于PNG而言,这应该不是一个问题,因为有效PNG中的最后一个字节应为0x82,即空IEND块CRC总和中的最低有效字节。


1
如果您想要更多的反斜线,请使用: sed s/\\\\/\\\\\\\\/g\;s/%/%%/g\;s/\\x00/\\\\x00/g
Karel Vlk
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.