在 shell 脚本中嵌入可执行二进制文件
首先,我已经在 Google 上搜索过,但只找到了将压缩文件(例如 .tar.gz
)嵌入到 shell 脚本中的示例.
First, I already googled but only found examples where a compressed file (say a .tar.gz
) is embedded into a shell script.
基本上,如果我有一个打印字符串的 C 程序 (hello.c
),比如 Hello World!.
Basically if I have a C program (hello.c
) that prints a string, say Hello World!.
我编译它以获得可执行的二进制文件
I compile it to get an executable binary
gcc hello.c -o hello
现在我有一个 shell 脚本 testEmbed.sh
Now I have a shell script testEmbed.sh
我要问的是是否可以将二进制文件 (hello) 嵌入到 shell 脚本中,以便在我运行时
What I am asking is if it is possible to embed the binary (hello) inside the shell script so that when I run
./testEmbed.sh
它执行二进制文件以打印 Hello World!.
it executes the binary to print Hello World!.
说明:一种替代方法是我将可执行文件压缩到存档中,然后在脚本运行时将其解压缩.我要问的是是否可以在没有它的情况下运行该程序.
Clarification: One alternative is that I compress the executable into an archive and then extract it when the script runs. What I am asking is if it is possible to run the program without that.
到目前为止,我一直在尝试这里的方法.但这对我不起作用.我猜作者是在另一个架构上使用其他发行版.所以,基本上这对我不起作用.:P
Up until now, I was trying the method here. But it does not work for me. I guess the author was using some other distribution on another architecture. So, basically this did not work for me. :P
另外,如果 C 程序的工作流程与 Java jar
不同,我也想知道!
Also, if the workflow for a C program differs from a Java jar
, I would like to know that too!
推荐答案
是的,可以这样做.它实际上与您链接的文章在概念上非常相似.诀窍是使用 uuencode
将二进制文件编码为文本格式,然后将其附加到脚本的末尾.
Yes, this can be done. It's actually quite similar in concept to your linked article. The trick is to use uuencode
to encode the binary into text format then tack it on to the end of your script.
然后您的脚本以这样的方式编写,它在自身上运行 uudecode
以创建二进制文件,更改权限然后执行它.
Your script is then written in such a way that it runs uudecode
on itself to create a binary file, change the permissions then execute it.
uuencode
和 uudecode
最初是为了将二进制内容转移到互联网的前身而创建的,互联网不能很好地处理二进制信息.转换为文本意味着它也可以作为 shell 脚本提供.如果,由于某种原因,当您尝试运行 uuencode
时您的发行版报错,这可能意味着您必须安装它.例如,在 Debian Squeeze 上:
uuencode
and uudecode
were originally created for shifting binary content around on the precursor to the internet, which didn't handles binary information that well. The conversion into text means that it can be shipped as a shell script as well. If, for some reason your distribution complains when you try to run uuencode
, it probably means you have to install it. For example, on Debian Squeeze:
sudo aptitude install sharutils
将为您获取相关的可执行文件.这是我经历的过程.首先创建并编译你的 C 程序 hello.c
:
will get the relevant executables for you. Here's the process I went through. First create and compile your C program hello.c
:
pax> cat hello.c
#include <stdio.h>
int main (void) {
printf ("Hello
");
return 0;
}
pax> gcc -o hello hello.c
然后创建一个shell脚本testEmbed.sh
,它会自己解码:
Then create a shell script testEmbed.sh
, which will decode itself:
pax> cat testEmbed.sh
#!/bin/bash
rm -f hello
uudecode $0
./hello
rm -f hello
exit
第一个 rm
语句表明 hello
可执行文件是由该脚本重新创建的,而不是在您的编译过程中徘徊.由于您还需要文件中的有效负载,请将编码的可执行文件附加到文件的末尾:
The first rm
statement demonstrates that the hello
executable is being created anew by this script, not left hanging around from your compilation. Since you need the payload in the file as well, attach the encoded executable to the end of it:
pax> uuencode hello hello >>testEmbed.sh
之后,当您执行脚本 testEmbed.sh
时,它会提取可执行文件并运行它.
Afterwards, when you execute the script testEmbed.sh
, it extracts the executable and runs it.
之所以如此,是因为 uudecode
在其输入(begin
和 end
)中查找由 uuencode
,所以它只尝试解码编码的程序,而不是整个脚本:
The reason this works is because uudecode
looks for certain marker lines in its input (begin
and end
) which are put there by uuencode
, so it only tries to decode the encoded program, not the entire script:
pax> cat testEmbed.sh
#!/bin/bash
rm -f hello
uudecode $0
./hello
rm -f hello
exit
begin 755 hello
M?T5,1@$!`0````````````(``P`!````$(,$"#0```#`!@```````#0`(``'
M`"@`'@`;``8````T````-(`$"#2`!`C@````X`````4````$`````P```!0!
: : :
M:&%N9&QE`%]?1%1/4E]%3D1?7P!?7VQI8F-?8W-U7VEN:70`7U]B<W-?<W1A
M<G0`7V5N9`!P=71S0$!'3$E"0UR+C``7V5D871A`%]?:38X-BYG971?<&-?
4=&AU;FLN8G@`;6%I;@!?:6YI=```
`
end
您可能还应该担心其他一些事情,例如您的程序可能需要目标系统上不存在的共享库,但上述过程基本上就是您所需要的.
There are other things you should probably worry about, such as the possibility that your program may require shared libraries that don't exist on the target system, but the process above is basically what you need.
JAR 文件的过程非常相似,只是运行它的方式不同.它仍然是一个文件,但您需要替换该行:
The process for a JAR file is very similar, except that the way you run it is different. It's still a single file but you need to replace the line:
./hello
带有能够运行 JAR 文件的东西,例如:
with something capable of running JAR files, such as:
java -jar hello.jar
相关文章