有没有办法在BASH脚本中存储二进制数据,以便以后可以通过该脚本传送给程序?
目前(在Mac OS X上)我正在做
play sound.m4a
# do stuff
我希望能够做到这样的事情:
SOUND <<< the m4a data, encoded somehow?
END
echo $SOUND | play
#do stuff
有办法做到这一点吗?
答案 0 :(得分:9)
Base64编码。例如:
$ openssl base64 < sound.m4a
然后在脚本中:
S=<<SOUND
YOURBASE64GOESHERE
SOUND
echo $S | openssl base64 -d | play
答案 1 :(得分:6)
我知道这就像骑死马,因为这篇文章相当陈旧,但我想提高Sionide21的答案,因为他的解决方案将二进制数据存储在一个不必要的变量中。
openssl base64 -d <<SOUND | play
YOURBASE64DATAHERE
SOUND
注意:HereDoc语法要求您不要缩进最后一个'SOUND' 当我缩进时,base64解码有时会失败 'YOURBASE64DATAHERE'部分。因此保留Base64是最佳做法 数据以及结束标记未缩进。
我发现这是寻找一种更优雅的方式来存储shell脚本中的二进制数据,但我已经像这里描述的那样解决了它。唯一的区别是我用这种方式运输一些tar-bzip文件。我的平台知道一个单独的base64二进制文件,因此我不必使用openssl。
base64 -d <<EOF | tar xj
BASE64ENCODEDTBZ
EOF
答案 2 :(得分:4)
有一种称为shar(shell存档)的Unix格式,允许您将二进制数据存储在shell脚本中。您可以使用shar
命令创建一个shar文件。
答案 3 :(得分:2)
当我完成这项工作后,我在这里使用了一个shell atob
。
function emit_binary {
cat << 'EOF' | atob
--junk emitted by btoa here
EOF
}
'EOF'
周围的单引号会阻止此文档正文中的参数扩展。
atob
和btoa
是非常旧程序,由于某种原因,它们通常不在现代Unix发行版中。效率稍低但更普遍的替代方法是使用mimencode -b
而不是btoa
。 mimencode
将编码为base64 ASCII。相应的解码命令是mimencode -b -u
而不是atob
。 openssl
命令也将执行base64编码。
答案 4 :(得分:1)
这是我很久以前写的一些代码,它将一个可选的可执行文件打包成一个bash脚本。我不记得它是如何工作的,但我怀疑你可以很容易地修改它来做你想做的事。
#!/usr/bin/perl
use strict;
print "Stub Creator 1.0\n";
unless($#ARGV == 1)
{
print "Invalid argument count, usage: ./makestub.pl InputExecutable OutputCompressedExecutable\n";
exit;
}
unless(-r $ARGV[0])
{
die "Unable to read input file $ARGV[0]: $!\n";
}
my $OUTFILE;
open(OUTFILE, ">$ARGV[1]") or die "Unable to create $ARGV[1]: $!\n";
print "\nCreating stub script...";
print OUTFILE "#!/bin/bash\n";
print OUTFILE "a=/tmp/\`date +%s%N\`;tail -n+3 \$0 | zcat > \$a;chmod 700 \$a;\$a \${*};rm -f \$a;exit;\n";
close(OUTFILE);
print "done.\nCompressing input executable and appending...";
`gzip $ARGV[0] -n --best -c >> $ARGV[1]`;
`chmod +x $ARGV[1]`;
my $OrigSize;
$OrigSize = -s $ARGV[0];
my $NewSize;
$NewSize = -s $ARGV[1];
my $Temp;
if($OrigSize == 0)
{
$NewSize = 1;
}
$Temp = ($NewSize / $OrigSize) * 100;
$Temp *= 1000;
$Temp = int($Temp);
$Temp /= 1000;
print "done.\nStub successfully composed!\n\n";
print <<THEEND;
Original size: $OrigSize
New size: $NewSize
Compression: $Temp\%
THEEND
答案 5 :(得分:0)
由于默认情况下Python在OS X上可用,您可以执行以下操作:
ENCODED=$(python -m base64 foo.m4a)
然后解码如下:
echo $ENCODED | python -m base64 -d | play
答案 6 :(得分:0)
如果要使用单个数据块,我使用的技巧是在文件末尾添加“数据开始”标记,然后在脚本中使用sed过滤掉主要内容。例如,将以下内容创建为“play-sound.bash"
:
#!/bin/bash
sed '1,/^START OF DATA/d' $0 | play
exit 0
START OF DATA
然后,您可以将数据附加到此文件的末尾:
cat sound.m4a >> play-sound.bash
现在,执行脚本应直接播放声音。