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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3122254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:15:33  来源:igfitidea点击:

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

bashscriptingbinaryuudecode

提问by Jeremy Friesner

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. The contents of the file need to be contained inside the script itself (i.e. I don't want to just package the file along with the script).

我有一个 bash 脚本专家在这里有点困惑……我有一个 bash 脚本,它需要在运行时创建一个小的(80 字节)二进制文件。文件的内容需要包含在脚本本身中(即我不想只将文件与脚本一起打包)。

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. 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. Any ideas?

...在上述运行后,我有我的文件/tmp/dummy.wav。但我刚刚发现运行这个脚本的计算机没有安装 uudecode(我不允许安装它),所以我需要找到其他方法来创建这个文件。有任何想法吗?

采纳答案by ninjalj

Some installers do something similar to this:

一些安装程序会做类似的事情:

#!/bin/bash
tail -n +4 
perl -ne 'print unpack("u",$_)' > dummy.wav <<EOD
M4DE&1D@```!7059%9FUT(!`````#``$``'<!``#<!0`$`"``9F%C=`0`````
C````4!2Q`````!````0#8E3```````````9&%T80``````
EOD
| tar xvzf - exit <tgz file appended here><newline>

回答by Daniel Martin

If the target computer has perlavailable:

如果目标计算机perl可用:

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

That's using the non-base64 format you get from just doing uuencode dummy.wav < dummy.wavon your original computer.

那是使用您uuencode dummy.wav < dummy.wav在原始计算机上执行的非 base64 格式。

Failing that, you can always do this:

否则,您始终可以这样做:

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

This little bit of bash was generated with:

这一点点的 bash 是通过以下方式生成的:

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

Edited to add: As pointed out in a reply here, something like this is also a possibility:

编辑添加:正如这里的回复所指出的那样,也有可能发生这样的事情:

#!/bin/bash
exec<
#!/bin/bash

# Define usage help
usage () {
    echo -e "USAGE:\n\t
#! /bin/bash

cat <<EOF | base64 -d > wherever-it-goes.bin
UtEOtUaZcUCrEJtPJrA34BH8Wdpxb1/DtfMo5syiE/h+moNyApEkg2ZwA2/jTDdfl4WijnNbMzvZ
RrF3i7X353AjmTjLBz1NcOOJJhRPYLJ4WQYONyYj/fAhnXQd+s4SHaNponOWKj1AAzdlJY1VLWaX
P8QBJQcn2FTL4pJ3N04=
EOF
<file to create> <dir to tar> <name of script or command to run>\n" exit 0 } # check commandline arguments if [ "" = "-h" ]; then usage; fi if [ -z ]; then usage; fi if [ -z ]; then usage; fi if [ -z ]; then usage; fi # test for the directory and if it exists, create the bin file using tar if [ -d "" ]; then cat ><<EOF #!/bin/sh -e sed -e '1,/^exit$/d' "$0" | tar xzf - && ".//" exit EOF tar czf - >> else echo " does not exist, aborting!" exit 1 fi # make the new file executable and exit chmod +x exit 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==

(the -dargument is important to turn off xargs's own backslash processing)

-d参数对于关闭xargs自己的反斜杠处理很重要)

You can also turn the 8/1in my hexdump command into 80/1and have a single long echoline.

您还可以将8/1我的 hexdump 命令中的 变成80/1并有一个长echo行。

回答by Ignacio Vazquez-Abrams

Put an exitat the end of your script, append the file to the end of the script, and use tail -c 80to get at the contents. This will work as long as you don't need to worry about newline conversion issues.

将 anexit放在脚本的末尾,将文件附加到脚本的末尾,并使用它tail -c 80来获取内容。只要您不需要担心换行符转换问题,这就会起作用。

回答by pizza

This is another example to decode radix 64 formatted data, it runs slow, but it is functional.

这是解码基数 64 格式数据的另一个示例,它运行缓慢,但可以正常工作。

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

回答by Ken H

##代码##

回答by Rakasa

I would use base64 encoding, as that seems to be the general replacement for uu encoding, and operates on very similar principles.

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

回答by Toni Homedes i Saun

Just encode the binary data in base64 and do something like this:

只需在 base64 中对二进制数据进行编码,然后执行以下操作:

##代码##

回答by Maddin

From my point of view uuencode and uudecode are essential, but that's only my opinion. Without creating temporary files you could also do something like this (uudecode.sh):

从我的角度来看 uuencode 和 uudecode 是必不可少的,但这只是我的意见。在不创建临时文件的情况下,您也可以执行以下操作 (uudecode.sh):

##代码##