2010-06-26 8 views
6

Mam tutaj małą puzzler dla ekspertów od skryptów bash ... Mam skrypt bash, który musi utworzyć mały (80-bajtowy) plik binarny, gdy będzie działał. Zawartość pliku musi być zawarta w samym skrypcie (tzn. Nie chcę po prostu pakować pliku razem ze skryptem).W jaki sposób skrypt bash może zapisać plik binarny bez użycia uudecode?

Mój skrypt obecnie robi to tak:

echo 'begin-base64 644 dummy.wav' > /tmp/dummy.uu 
echo 'UklGRkgAAABXQVZFZm10IBAAAAADAAEAAHcBAADcBQAEACAAZmFjdAQAAAAAAAAAUEVBSxAAAAAB' >> /tmp/dummy.uu 
echo 'AAAAQDYlTAAAAAAAAAAAZGF0YQAAAAA=' >> /tmp/dummy.uu 
echo '====' >> /tmp/dummy.uu 
uudecode -o /tmp/dummy.wav /tmp/dummy.uu 
rm /tmp/dummy.uu 

... po powyższych tras, mam pliku /tmp/dummy.wav. Ale właśnie dowiedziałem się, że komputer, na którym uruchamiany jest ten skrypt, nie ma zainstalowanego uudecode (i nie mam uprawnień do jego instalacji), więc muszę znaleźć inny sposób na utworzenie tego pliku. Jakieś pomysły?

Odpowiedz

6

Niektórzy instalatorzy zrobić coś podobnego do tego:

#!/bin/bash 
tail -n +4 $0 | tar xvzf - 
exit 
<tgz file appended here><newline> 
1

położyć exit na końcu skryptu, dołącz plik na końcu skryptu i korzystania tail -c 80 dostać się na treści. Będzie działać tak długo, jak długo nie będziesz musiał się martwić o problemy z konwersją newline.

6

Jeśli komputer docelowy ma perl dostępne:

perl -ne 'print unpack("u",$_)' > dummy.wav <<EOD 
M4DE&[email protected]```!7059%9FUT(!`````#``$``'<!``#<!0`$`"``9F%C=`0````` 
C````4$5!2Q`````!````0#8E3```````````9&%T80`````` 
EOD 

Że używa formatu non-base64 można uzyskać z właśnie robi uuencode dummy.wav < dummy.wav na oryginalnym komputerze.

przeciwnym razie, zawsze można to zrobić:

echo -ne '\x52\x49\x46\x46\x48\x00\x00\x00' > dummy.wav 
echo -ne '\x57\x41\x56\x45\x66\x6d\x74\x20' >> dummy.wav 
echo -ne '\x10\x00\x00\x00\x03\x00\x01\x00' >> dummy.wav 
echo -ne '\x00\x77\x01\x00\x00\xdc\x05\x00' >> dummy.wav 
echo -ne '\x04\x00\x20\x00\x66\x61\x63\x74' >> dummy.wav 
echo -ne '\x04\x00\x00\x00\x00\x00\x00\x00' >> dummy.wav 
echo -ne '\x50\x45\x41\x4b\x10\x00\x00\x00' >> dummy.wav 
echo -ne '\x01\x00\x00\x00\x40\x36\x25\x4c' >> dummy.wav 
echo -ne '\x00\x00\x00\x00\x00\x00\x00\x00' >> dummy.wav 
echo -ne '\x64\x61\x74\x61\x00\x00\x00\x00' >> dummy.wav 

To trochę bash został wygenerowany z:

$ hexdump -e '"echo -ne '\''" 8/1 "x%02x" "'\'' >> dummy.wav\n"' dummy.wav | sed 's;x;\\x;g;1s/>/ /' 

Zmieniano dodać: Jak wskazano w odpowiedzi tu coś taka jest również możliwość:

xargs -d'\n' -n1 echo -ne > dummy.wav <<EOD 
\x52\x49\x46\x46\x48\x00\x00\x00\x57\x41\x56\x45\x66\x6d\x74\x20 
\x10\x00\x00\x00\x03\x00\x01\x00\x00\x77\x01\x00\x00\xdc\x05\x00 
\x04\x00\x20\x00\x66\x61\x63\x74\x04\x00\x00\x00\x00\x00\x00\x00 
\x50\x45\x41\x4b\x10\x00\x00\x00\x01\x00\x00\x00\x40\x36\x25\x4c 
\x00\x00\x00\x00\x00\x00\x00\x00\x64\x61\x74\x61\x00\x00\x00\x00 
EOD 

(-d argument jest ważne, aby wyłączyć własne przetwarzanie ukośnika xargs „s)

Można również włączyć 8/1 w moim komendy zrzutu heksowego do 80/1 i mieć jeden długi echo linię.

+0

można użyć tego samego tutaj funkcję doc z wersją Bash ze zbiegłych wartości hex i uniknąć wszystkich tych echa i '' >> dołącza. –

+0

Dodano wersję, używając tutaj-doc i bez '' '. –

0

Z mojego punktu widzenia niezbędne są uuencode i uudecode, ale to tylko moja opinia. bez tworzenia plików tymczasowych można też zrobić coś tak (uudecode.sh):

#!/bin/bash 
# -- 
# -- Uudecoding without using a regular temporary file 
# -- 

# -- Create a named pipe: 
mknod /tmp/.dummypipe p 

# -- Starting uudecoding on that pipe in the background: 
uudecode -o dummy.txt /tmp/.dummypipe & 

# -- Push base64-uuencoded content into the named pipe: 
cat <<END_DUMMY > /tmp/.dummypipe 
begin-base64 644 dummy.txt 
VGhpcyBpcyB0aGUgdXVkZWNvZGVkIHRleHQuCg== 
==== 
END_DUMMY 

# -- Remove the named pipe 
rm /tmp/.dummypipe 
+0

OP powiedział, że nie ma uudecode, twój skrypt używa uudecode. –

1

Jest to kolejny przykład dekodowania radix 64 sformatowanych danych, działa powoli, ale jest funkcjonalne.

#!/bin/bash 
exec<$0 
while read line ; do if [ "$line" = "#payload" ] ; then break; fi; done 
r64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/' 
i=0; while [ $i -lt 256 ] ; do tab[$i]=-1 ; let i=$i+1 ;done 
i=0; while [ $i -lt 64 ] ; do tab[`printf "%d" "'${r64:$i:1}"`]=$i ; let i=$i+1; done 
bi=0 
while read -n 1 x 
do 
in=${tab[`printf "%d" "'$x"`]} 
if [ $in -ge 0 ]; then case $bi in 
    0) out=$(($in<<2)); bi=6 ;; 
    2) out=$(($out|$in)); printf \\$(printf '%03o' $(($out&255))); bi=0 ;; 
    4) out=$(($out+($in>>2))); printf \\$(printf '%03o' $(($out&255))); 
    bi=0; out=$(($in<<6)); bi=2 ;; 
    *) out=$(($out+($in>>4))); printf \\$(printf '%03o' $(($out&255))); 
    bi=0; out=$(($in<<4)); bi=4 ;; 
    esac fi 
done 
exit 
#payload 
dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2XmAgICAte3Z2dnZ2dnZ2dnZ2dnZ2dgp2dnZ2dnZ2dnZ2dnZ2dnZ2PiAg 
ICAgIC4gLXZ2dnZ2dnZ2dnZ2dnZ2CnZ2dnZ2dnZ2dnZ2dnZ2dn0gICAgICAgPT4gLXZ2dnZ2dnZ2dnZ2 
dnYKdnZ2dnZJdnZJdnZJdnZJOyAgICAgICAtICAgPXZJdkl2dkl2dkl2dgp2dnZ2SXZ2dnZ2dnZ2dnZg 
ICAgICAgICAgICAgbnZ2dnZJdnZ2dnZ2CnZ2dnZ2dnZ2SXZJdnZJdiAgIC4gICAgICwgICA8dnZ2SXZ2 
dkl2dkkKdnZ2SXZ2SXZ2dnZ2SXZJIF9zOyAgX3VvLyAgID12dnZ2dnZ2dnZJdgp2dnZ2dkl2dnZJdnZ2 
dnYgdyRtICBtQCRtICAgPXZ2dnZJdnZJdnZ2CnZ2dnZJdnZ2dnZ2dkl2SSBmPTQuO1cgYFE7ICA9dnZ2 
dnZ2dnZ2dnYKdnZ2SXZ2dnZJdnZJdnZ2IHQtM3MlJiAgbWAgID12dnZ2SXZJdnZJdgp2dnZ2dnZ2SXZ2 
dnZ2dnYgXWlvWjZYYXVQICAgPXZ2dnZ2dnZ2SXZ2CnZ2dkl2dkl2dnZJdnZJdi4pbVojWlojWlMgICAu 
dnZ2SXZJdnZ2dnYKdnZ2dnZ2dnZ2dnZ2SXZ2OjNYWlpaI1pTWCAgICB7dnZ2dnZ2dkl2dgp2dnZ2SXZ2 
SXZ2SXZ2dnY7PFNYWlhTZFhuIC5pLj12dnZJdnZJdnZ2CnZ2dkl2dnZ2dkl2dnZ2dmBdJVhYWlhubW0+ 
IC1gIHZ2dnZ2dnZ2dnYKdnZ2dnZ2SXZ2dnZ2SXYlIGptdklud1FXUW0gICAgPHZ2SXZ2SXZ2SQp2dnZJ 
dnZ2dkl2dkl2dmAuUVFvWG1tUVFRUWMgICAge0l2dnZ2dnZ2CnZ2dnZ2dkl2dnZ2dnYrIGpRV1FtV1FR 
UVFRayAgICAtdnZ2dkl2dkkKdnZ2dkl2dnZ2SXZJPiBfUVFRUVFRUVFRUVFRLiAgICA9dkl2dnZ2dgp2 
dnZJdnZ2SXZ2dmwgIF1RUVFRV1FRUVdXOCRMICAgICA8dnZ2SXZ2CnZ2dnZ2dnZ2dnZ2OyAgbm1RUVFt 
UVFRbXdvb20gLiAgIC1JdnZ2dnYKdnZ2SXZ2SXZ2SX0gID1RV1FRUVFRUVFRUVFtMlsgLSAgID12dkl2 
dgp2dnZ2dnZ2dkl2Oy4gZFFRUVFRUVFRUVFRUVFRcSAgLiAgIEl2dnZ2CnZ2dnZJdkl2dnZgLjxRUVFR 
UVFRUVFRUVFRUVdRKC4uLiAgPEl2dnYKdnZ2SXZ2dnZ2PiAgZFFRUVFRUVFRUVFRUVFRUVFbICAuICAg 
dnZ2SQp2dnZ2dnZ2dnYnIC5RUVFRUVFRUVFRUVFRUVFRUWsgIC4gICB7dnZ2CnZ2dkl2dkl2PiAuXVFR 
UVFRV1dXUVFRUVFRUVFRbSAgICAgIClsdnYKdnZ2dnZ2dnZgIDpqUVFRUVEjUVdRUVFRUVFRUVFXICAu 
ICAgOnZ2SQp2dnZ2SXZ2bCAgOmpXUVFRUUVXV1FRUVFRV1FRUVcgIGAgICA6dnZ2CnZ2dkl2dnZJLl86 
alFRUVFRRVdRUVFRUVFRUVFRVyAuIC4uID12dnYKdnZ2dnZ2dnZkIzYvUVdRUVFFUVFRUVFRUVFRV1dM 
LiAgIDogKXZ2dgp2dnZJdnZJMyNaWkwtJFFRUVFRV1FRUVFRUVFCWiNgICAgLmRvdnZ2CnZ2dnZ2SXZa 
IyMjWj4tNFFRUVdRUVFRUVFRUUVaay4gICBqWlh2dnYKdnZ2dndvbVgjWiNaIy4gNFFRUVFRUVFRUVdX 
MVpYc189dVhaaHZ2dgp2dnZaWiNaI1VVWiNaTCAgXVFRUVFRUVFRUVdlWFpYcVhtWiNVenZ2CnZ2SVgj 
I1ojWiMjWiNaLyAuUVFRUVFRUVFRVzEzI1paWlojWiMjb3YKdnZ2ZFVaIyNVWiMjVVVoX2FRUVFRUVFR 
UVFQOlhaIyNVI1ojVVojaAp2dklkIyNaI1ojI1ojWlpaV1FRUVFRUVFXUCA9ZFojWiNaIyNaIyNaCnZ2 
dlojWiMjVVVaI1ojWlpKUVFRUVFXUF4gIClYIyNaI1VVWiNVWjEKdnZ7WlojWlVaIyNaIyNaVXMtIT8i 
fiAgICAgdlgjWiMjWiNaWF5sdgp2bCBZWFhYWFpaVVUjWlpaMS4gICAgICAgICB2WFojWiNaWCIgIDx2 
CnZzICAtfiJJMVhYWFpaWm8xICAgICAgICAgIEluWFhaU31gICAgPHYKdnY7ICAgICAtLTwxMjIxbGAg 
ICAgICAgICAgPElubjF9ICAgICB2SQp2dmwsICAgICAgICB+Kz5gICAgICAgICAgICAgfnwrfiAgICAu 
JUl2CnZ2dnZpLiAgICAgICAgICAgIF9pc2ksICAgICAgICAgICAgX3ZJdnYKdnZ2dnZ2c19fXy4uLi5f 
XyV2dnZ2SXZpLCxfLiAuLl9fPnZ2dnZ2dgp2dnZ2SXZ2dm52dnZ2dnZudnZ2dnZ2dnZubnZ2dnZ2dnZ2 
dnZ2dnZ2Cg== 
1
#!/bin/bash 

# Define usage help 
usage() { 
    echo -e "USAGE:\n\t$0 <file to create> <dir to tar> <name of script or command to run>\n" 
    exit 0 
} 

# check commandline arguments 
if [ "$1" = "-h" ]; then usage; fi 
if [ -z $1 ]; then usage; fi 
if [ -z $2 ]; then usage; fi 
if [ -z $3 ]; then usage; fi 

# test for the directory and if it exists, create the bin file using tar 
if [ -d "$2" ]; then 
    cat >$1<<EOF 
#!/bin/sh -e 
sed -e '1,/^exit$/d' "\$0" | tar xzf - && "./$2/$3" 
exit 
EOF 
    tar czf - $2 >> $1 
else 
    echo "$2 does not exist, aborting!" 
    exit 1 
fi 

# make the new file executable and exit 
chmod +x $1 
exit 0 
+0

Ten przykład byłby lepszy, gdybyś go rozebrał tylko na podstawowe zasady pisania pliku binarnego i wyjaśnił, co robi i dlaczego działa. –

1

użyłbym kodowanie base64, jako że wydaje się być zamiennikiem dla ogólnego kodowania uu, a działa na bardzo podobnych zasadach.

+0

Witamy w Stack Overflow i podziękowania za wkład. Jednak to nie jest kompletna odpowiedź. Wyjaśnienie, jakie polecenia, których użyjesz do odkodowania pliku, znacznie ułatwiłoby jego wykonanie. Działający przykładowy kod byłby jeszcze lepszy. – jerry

0

Wystarczy kodowania danych binarnych w formacie base64 i zrobić coś takiego:

#! /bin/bash 

cat <<EOF | base64 -d > wherever-it-goes.bin 
UtEOtUaZcUCrEJtPJrA34BH8Wdpxb1/DtfMo5syiE/h+moNyApEkg2ZwA2/jTDdfl4WijnNbMzvZ 
RrF3i7X353AjmTjLBz1NcOOJJhRPYLJ4WQYONyYj/fAhnXQd+s4SHaNponOWKj1AAzdlJY1VLWaX 
P8QBJQcn2FTL4pJ3N04= 
EOF 
Powiązane problemy