Хранение файлов внутри скриптов BASH

есть ли способ хранить двоичные данные внутри скрипта BASH, чтобы его можно было передать в программу позже в этом скрипте?

на данный момент (на Mac OS X) я делаю

play sound.m4a
# do stuff

Я хотел бы иметь возможность сделать что-то вроде:

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

есть ли способ сделать это?

7 ответов


Base64 кодирует его. Например:

$ openssl base64 < sound.m4a

а потом в скрипт:

S=<<SOUND
YOURBASE64GOESHERE
SOUND

echo $S | openssl base64 -d | play

Я знаю, что это похоже на езду на мертвой лошади, так как этот пост довольно старый, но я хотел бы улучшить ответ Sionide21, поскольку его решение хранит двоичные данные в переменной, которая не нужна.

openssl base64 -d <<SOUND | play
YOURBASE64DATAHERE
SOUND

Примечание: синтаксис HereDoc требует, чтобы вы не отступали последний "звук" и декодирование base64 иногда не удавалось мне, когда я отступал, что Раздел "YOURBASE64DATAHERE". Так что лучше всего сохранить Base64 Данные, а также конечный токен unindented.

Я ищу более элегантный способ хранения двоичных данных в Shell-скриптах, но я уже решил его, как описано здесь. Единственная разница в том, что я перевозил некоторые файлы tar-bzipped таким образом. Моя платформа знает отдельный двоичный файл base64, поэтому мне не нужно использовать openssl.

base64 -d <<EOF | tar xj
BASE64ENCODEDTBZ
EOF

существует формат Unix под названием Шарья (Shell archive), который позволяет хранить двоичные данные в сценарии оболочки. Вы создаете файл shar с помощью .


когда я это сделал, я использовал оболочку здесь документ, пропущенный через atob.

function emit_binary {
  cat << 'EOF' | atob
  --junk emitted by btoa here
  EOF
}

одинарные кавычки вокруг 'EOF' запретить расширение параметров в теле документа here.

atob и btoa are очень старые программы, и по какой-то причине они часто отсутствуют в современных дистрибутивах Unix. Несколько менее эффективной, но более вездесущей альтернативой является использование mimencode -b вместо btoa. mimencode будет кодировать в кодировке base64 кодировке ASCII. Соответствующая команда декодирования -mimencode -b -u вместо atob. The openssl команда также будет выполнять кодировку base64.


вот код, который я написал давно, который упаковывает исполняемый файл выбора в скрипт 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

поскольку Python доступен в OS X по умолчанию, вы можете сделать следующее:

ENCODED=$(python -m base64 foo.m4a)

затем расшифровать его, как показано ниже:

echo $ENCODED | python -m base64 -d  | play

Если это один блок данных для использования, трюк, который я использовал, заключается в том, чтобы поместить маркер "начало данных" в конце файла, а затем использовать sed в скрипте для фильтрации ведущих материалов. Например, создайте следующее Как"play-sound.bash":

#!/bin/bash

sed '1,/^START OF DATA/d'  | play
exit 0
START OF DATA

затем, вы можете просто добавить данные в конец этого файла:

cat sound.m4a >> play-sound.bash

и теперь, выполнение сценария должно воспроизводить звук напрямую.