Хранение файлов внутри скриптов BASH - PullRequest
10 голосов
/ 22 февраля 2010

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

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

play sound.m4a
# do stuff

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

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

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

Ответы [ 7 ]

9 голосов
/ 22 февраля 2010

Base64 закодировать его. Например:

$ openssl base64 < sound.m4a

, а затем в сценарии:

S=<<SOUND
YOURBASE64GOESHERE
SOUND

echo $S | openssl base64 -d | play
6 голосов
/ 16 августа 2013

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

openssl base64 -d <<SOUND | play
YOURBASE64DATAHERE
SOUND

Примечание. Синтаксис HereDoc требует, чтобы вы не делали отступ для последнего 'SOUND' и декодирование Base64 иногда не на меня, когда я отступил, что Раздел «YOURBASE64DATAHERE». Так что лучше всего придерживаться Base64 Данные, а также конечный токен с отступом.

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

base64 -d <<EOF | tar xj
BASE64ENCODEDTBZ
EOF
4 голосов
/ 22 февраля 2010

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

2 голосов
/ 22 февраля 2010

Когда я это сделал, я использовал здесь оболочку документа, пропущенного через 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.

1 голос
/ 22 февраля 2010

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

Если используется один блок данных, я использовал хитрость, заключающуюся в том, чтобы поместить маркер «начало данных» в конец файла, а затем использовать 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

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

0 голосов
/ 25 мая 2015

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

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

Затем расшифруйте его, как показано ниже:

echo $ENCODED | python -m base64 -d  | play
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...