将文件存储在BASH脚本中

时间:2010-02-22 01:22:04

标签: bash

有没有办法在BASH脚本中存储二进制数据,以便以后可以通过该脚本传送给程序?

目前(在Mac OS X上)我正在做

play sound.m4a
# do stuff

我希望能够做到这样的事情:

SOUND <<< the m4a data, encoded somehow?
END
echo $SOUND | play
#do stuff

有办法做到这一点吗?

7 个答案:

答案 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'周围的单引号会阻止此文档正文中的参数扩展。

atobbtoa非常旧程序,由于某种原因,它们通常不在现代Unix发行版中。效率稍低但更普遍的替代方法是使用mimencode -b而不是btoamimencode将编码为base64 ASCII。相应的解码命令是mimencode -b -u而不是atobopenssl命令也将执行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

现在,执行脚本应直接播放声音。