Bash能够处理二进制数据吗?
基本上,答案是否定的。
尽管bash的二进制数据处理能力比旧的shell要强,但它仍然无法处理任意二进制数据。具体而言,shell变量不是100%的二进制清洁的,因此不能在它们中存储二进制文件。
您可以将uuencode的ASCII数据存储在变量中,例如:
var=$(uuencode /bin/ls ls)
cd /somewhere/else
uudecode <<<"$var" # 不要忘记加引号!
请注意:GNU和Unix的uuencode/uudecode之间有很大的区别。在Unix的uudecode中,您无法指定输出文件;它总是使用在ASCII数据中编码的文件名。我已经修复了以前的示例,使其在Unix系统上可以工作。如果您进行进一步更改,请不要使用GNUisms。
有时候,在使用netpbm时存储小的临时位图文件会很方便。在这种情况下,我通过在管道中添加pnmnoraw命令来创建(较大的)ASCII文件,这样bash在存储时不会出现问题。
如果您有冒险精神,请考虑进行以下实验:
# bindec.bash,尝试将二进制数据解码为ASCII十进制数据
IFS=
while read -n1 x ;do
case "$x" in
'') echo empty ;;
# 在此处插入以下单行代码生成的256行代码:
# for x in $(seq 0 255) ;do echo " #39;\\$(printf %o $x)') echo $x;;" ;done
esac
done
然后将二进制数据输入到它中,例如:
for x in $(seq 0 255) ;do echo -ne "\\$(printf %o $x)" ;done | bash bindec.bash | nl | less
这表明0字符被完全跳过了,因为我们无法使用输入生成它,因此大多数我们尝试处理的二进制文件会方便地遭到破坏。
是的,Bash是用C编写的,并使用C语义来处理字符串(包括NUL字节作为字符串终止符)在其变量中。您无法在Bash变量中安全地存储NUL。它从来没有打算用于这个目的。--GreyCat
请注意,这指的是将二进制数据存储在变量中。使用管道在程序之间移动数据始终是二进制清洁的。临时文件也是安全的,只要在创建它们时采取适当的预防措施。
如果没有外部命令可用,只使用bash内置命令来cat二进制文件(当/lib/libgcc_s.so.1被重命名时,我曾经使用过这个技巧,挽救了当时的局面):
# 仅使用bash内置命令模拟cat,二进制安全
IFS=
while read -d '' -r -n1 x ; do
case "$x" in
'') printf "\x00";;
*) printf "%s" "$x";;
esac
done
如果没有-n1,您必须小心处理最后一个\0后的数据,例如循环后[[ $x ]] && printf "%s" "%x"。我没有测试过它是否可行或是否足够。此外,如果您读取一个没有任何\0的大文件,我不知道会发生什么。--pgas
知识点: uunencode命令行工具
在 Bash 中,uuencode 是一个用于将二进制文件转换成可打印的 ASCII 码表示形式的命令。该命令的语法如下:
uuencode [输入文件] [输出文件]
其中,输入文件是要编码的二进制文件,输出文件是编码后的 ASCII 码文件。uuencode 命令将输入文件转换成一种称为 uuencode 格式的 ASCII 码表示形式,并将结果输出到输出文件中。
uuencode 命令通常用于将二进制文件转换成文本格式,以便通过电子邮件或其他文本传输方式发送。由于某些电子邮件系统只能传输文本数据,因此 uuencode 可以将二进制文件编码成文本格式,然后再通过电子邮件发送。
要解码 uuencode 编码的文件,可以使用 Bash 中的 uudecode 命令。uudecode 命令将 uuencode 格式的 ASCII 码文件解码为原始的二进制文件。
uuencode 命令可以将二进制文件编码为 ASCII 码格式,以便通过电子邮件等文本传输方式发送,而 uudecode 命令可以将 uuencode 格式的 ASCII 码文件解码为原始的二进制文件。
如果在 Bash 中运行 uuencode 命令时出现 "uuencode: 未找到命令" 的错误消息,可能是因为 uuencode 命令没有安装或没有添加到系统的 PATH 环境变量中。
在大多数 Linux 发行版中,uuencode 命令通常包含在 sharutils 或 uuencode 包中。您可以使用以下命令来安装它们:
在基于 Debian 或 Ubuntu 的系统中:
sudo apt-get install sharutils
在基于 Red Hat 或 CentOS 的系统中:
sudo yum install sharutils
在安装完成后,您可以尝试再次运行 uuencode 命令,如果仍然出现相同的错误消息,则需要检查 PATH 环境变量是否包含 uuencode 命令所在的目录。可以使用以下命令来查看 PATH 环境变量的值:
echo $PATH
如果 uuencode 命令所在的目录没有包含在 PATH 环境变量中,可以使用以下命令将其添加到 PATH 环境变量中(假设 uuencode 命令所在的目录为 /usr/bin):
export PATH=$PATH:/usr/bin
添加完毕后,您可以再次尝试运行 uuencode 命令,应该就可以正常工作了。
了解更多shell实用技巧,快速掌握大厂一线经验
如果您觉得文章内容对你有一点帮助可以关注我,我在头条平台会持续分享更多实用的shell技巧和最佳实践,如果想系统的快速学习shell的各种高阶用法和生产环境避坑指南可以看看《shell脚本编程最佳实践》专栏,专栏里有更多的实用小技巧和脚本代码分享。