2010-06-26 13 views
6

Tengo un pequeño rompecabezas aquí para los expertos en scripts bash ... Tengo un script bash que necesita crear un pequeño archivo binario (80 bytes) cuando se ejecuta. El contenido del archivo debe estar contenido dentro del mismo script (es decir, no quiero simplemente empacar el archivo junto con el script).¿Cómo puede un script bash escribir un archivo binario, sin usar uudecode?

Mi script actualmente lo hace así:

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 

... después de las carreras anteriores, tengo mi archivo /tmp/dummy.wav. Pero descubrí que la computadora en la que se ejecuta esta secuencia de comandos no tiene uudecode instalado (y no tengo permiso para instalarlo), así que necesito encontrar otra forma de crear este archivo. ¿Algunas ideas?

Respuesta

6

Algunos instaladores hacen algo similar a esto:

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

poner exit al final de la secuencia de comandos, añada el archivo al final del guión, y el uso tail -c 80 para llegar a los contenidos. Esto funcionará siempre y cuando no tenga que preocuparse por los problemas de conversión de la nueva línea.

6

Si el equipo de destino tiene perl disponibles:

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 

que está utilizando el formato de base 64 no se obtiene a partir de sólo hacer uuencode dummy.wav < dummy.wav en su equipo original.

De no ser así, siempre se puede hacer esto:

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 

Este poco de fiesta se generó con:

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

Editado para agregar: Como se señaló en un comentario aquí, algo como esta también es una posibilidad:

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 

(el -d argumento es importante desactivar propio procesamiento barra invertida xargs 's)

También puede activar la 8/1 en mi comando hexdump en 80/1 y tienen una sola línea larga echo.

+0

Usted puede utilizar la misma función que aquí doc con la versión de Bash con los valores hexadecimales escapados y evitar todos esos ecos y '' >> Anexa –

+0

Se agregó una versión con un here-doc y no '>>'. –

0

Desde mi punto de vista uuencode y uudecode son esenciales, pero eso es solo mi opinión. sin crear archivos temporales también se podría hacer algo como esto (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

El OP dijo que no tiene uudecode, su script usa uudecode. –

1

Este es otro ejemplo de decodificar radix 64 datos formateados, corre lento, pero es funcional.

#!/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

Este ejemplo sería mejor si lo desglosó solo a lo esencial de escribir un archivo binario, y le explicó qué hace y por qué funciona. –

1

me gustaría utilizar la codificación base64, ya que parece ser el reemplazo general de codificación uu, y opera en principios muy similares.

+0

Bienvenido a Stack Overflow y gracias por la contribución. Sin embargo, esta no es realmente una respuesta completa. Explicar qué comandos utilizarías para decodificar el archivo ayudaría mucho a mejorarlo. El código de muestra de trabajo sería aún mejor. – jerry

0

Sólo codificar los datos binarios en base 64 y hacer algo como esto:

#! /bin/bash 

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