简体   繁体   English

bash脚本如何在不使用uudecode的情况下写出二进制文件?

[英]How can a bash script write out a binary file, without using uudecode?

I've got a little puzzler here for the bash scripting experts... I have a bash script that needs to create a small (80 byte) binary file when it runs. 我在这里为bash脚本专家提供了一些小问题...我有一个bash脚本,需要在运行时创建一个小的(80字节)二进制文件。 The contents of the file need to be contained inside the script itself (ie I don't want to just package the file along with the script). 文件的内容需要包含在脚本本身内(即我不想只是将文件与脚本一起打包)。

My script currently does it like this: 我的脚本目前这样做:

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

... after the above runs, I have my file /tmp/dummy.wav. ...在上面的运行之后,我有我的文件/tmp/dummy.wav。 But I just found out that the computer this script is to run on does not have uudecode installed (and I'm not allowed to install it), so I need to find some other way to create this file. 但我发现这个脚本运行的计算机没有安装uudecode(我不允许安装它),所以我需要找到一些其他的方法来创建这个文件。 Any ideas? 有任何想法吗?

Some installers do something similar to this: 一些安装程序执行类似于此的操作:

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

If the target computer has perl available: 如果目标计算机有perl可用:

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

That's using the non-base64 format you get from just doing uuencode dummy.wav < dummy.wav on your original computer. 这是使用你在原始计算机上执行uuencode dummy.wav < dummy.wav时获得的非base64格式。

Failing that, you can always do this: 如果做不到这一点,你可以随时这样做:

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

This little bit of bash was generated with: 这一点bash是通过以下方式生成的:

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

Edited to add: As pointed out in a reply here, something like this is also a possibility: 编辑添加:正如在这里的回复中所指出的,这样的事情也是可能的:

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

(the -d argument is important to turn off xargs 's own backslash processing) -d参数对于关闭xargs自己的反斜杠处理非常重要)

You can also turn the 8/1 in my hexdump command into 80/1 and have a single long echo line. 您也可以将我的hexdump命令中的8/1转换为80/1并使用一条长echo线。

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

我会使用base64编码,因为它似乎是uu编码的一般替代品,并且操作的原理非常相似。

Put an exit at the end of your script, append the file to the end of the script, and use tail -c 80 to get at the contents. 在脚本末尾放置一个exit ,将文件附加到脚本的末尾,然后使用tail -c 80来获取内容。 This will work as long as you don't need to worry about newline conversion issues. 只要您不需要担心新行转换问题,这将有效。

This is another example to decode radix 64 formatted data, it runs slow, but it is functional. 这是解码基数64格式数据的另一个例子,它运行缓慢,但它是有用的。

#!/bin/bash
exec<$0
while read line ; do if [ "$line" = "#payload" ] ; then break; fi; done
r64='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
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==

Just encode the binary data in base64 and do something like this: 只需在base64中编码二进制数据并执行以下操作:

#! /bin/bash

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

From my point of view uuencode and uudecode are essential, but that's only my opinion. 从我的观点来看,uuencode和uudecode是必不可少的,但这只是我的意见。 Without creating temporary files you could also do something like this (uudecode.sh): 在不创建临时文件的情况下,您也可以执行以下操作(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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Bash脚本写文件取决于内容 - Bash Script Write File Out Depending on Contents 如何将 heredoc 写入 Bash 脚本中的文件? - How can I write a heredoc to a file in Bash script? Bash脚本,可打印出一个二进制文件的内容,一次仅输出一个单词,而无需xxd - Bash script that prints out contents of a binary file, one word at a time, without xxd 如何在 bash 脚本中使用 jq 将 json output 写入 CSV 文件? - How to write json output to a CSV file using jq in a bash script? Bash脚本遍历子目录并写入文件,而无需使用find,ls等 - Bash script loop through subdirectories and write to file without using find,ls etc 如何将 Docker 命令脚本写入“单个单词”二进制文件? 使用 bash 脚本? - How can I script a Docker command into a 'single word' binary? Using bash script? 如何编写一个将自身转储到标准输出的 bash 脚本(用作帮助文件)? - How to write a bash script that dumps itself out to stdout (for use as a help file)? 使用 bash 脚本注释文件中的行 - Commenting out lines in a file using a bash script Bash脚本:使用管道将字符串写入文件而没有任何输出到终端 - Bash script: write string to file without any output to the terminal, using pipe 如何编写 bash 脚本来获取备份 - how can write bash script to get backup
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM