首先,我已经使用Google搜索,但只找到了将压缩文件(例如.tar.gz
)嵌入到shell脚本中的示例。
基本上,如果我有一个打印字符串的C程序(hello.c
),请说 Hello World!。
我编译它以获得可执行的二进制文件
gcc hello.c -o hello
现在我有一个shell脚本testEmbed.sh
我要问的是,是否可以在shell脚本中嵌入二进制文件( hello ),以便在运行时
./testEmbed.sh
它执行二进制文件以打印 Hello World!。
澄清: 另一种方法是将可执行文件压缩到一个存档中,然后在脚本运行时将其解压缩。我要问的是,如果没有它可以运行该程序。
到目前为止,我正在尝试here方法。但它对我不起作用。我想作者正在另一个架构上使用其他一些发行版。所以,基本上这对我不起作用。 :P
另外,如果C程序的工作流程与Java jar
不同,我也想知道!
答案 0 :(得分:15)
是的,这可以做到。它实际上与你的链接文章在概念上非常相似。诀窍是使用uuencode
将二进制文件编码为文本格式,然后将其添加到脚本的末尾。
然后编写脚本,使其在自身上运行uudecode
以创建二进制文件,更改权限然后执行它。
uuencode
和uudecode
最初是为了将二进制内容转移到互联网的前身而创建的,互联网并没有很好地处理二进制信息。转换为文本意味着它也可以作为shell脚本发布。如果由于某种原因,当您尝试运行uuencode
时,您的发布会抱怨,则可能意味着您必须安装它。例如,在Debian Squeeze上:
sudo aptitude install sharutils
将为您获取相关的可执行文件。这是我经历的过程。首先创建并编译您的C程序hello.c
:
pax> cat hello.c
#include <stdio.h>
int main (void) {
printf ("Hello\n");
return 0;
}
pax> gcc -o hello hello.c
然后创建一个shell脚本testEmbed.sh
,它将解码自己:
pax> cat testEmbed.sh
#!/bin/bash
rm -f hello
uudecode $0
./hello
rm -f hello
exit
第一个rm
语句表明此脚本正在重新创建hello
可执行文件,而不是在编译中留下。由于您还需要文件中的有效负载,请将编码的可执行文件附加到其末尾:
pax> uuencode hello hello >>testEmbed.sh
之后,当您执行脚本testEmbed.sh
时,它会提取可执行文件并运行它。
这可行的原因是因为uudecode
在begin
放置了输入(end
和uuencode
)中的某些标记行,因此它只会尝试解码编码的程序,而不是整个脚本:
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"0U\R+C``7V5D871A`%]?:38X-BYG971?<&-?
4=&AU;FLN8G@`;6%I;@!?:6YI=```
`
end
您可能还应该担心其他一些问题,例如您的程序可能需要目标系统上不存在的共享库,但上述过程基本上就是您所需要的。
JAR文件的过程非常相似,只是您运行它的方式不同。它仍然是单个文件,但您需要替换该行:
./hello
能够运行JAR文件,例如:
java -jar hello.jar
答案 1 :(得分:2)
我认为makeself就是你所描述的。
答案 2 :(得分:2)
执行此操作的可移植方法是使用printf
命令和八进制转义符:
printf '\001\002\003'
打印字节1,2和3.由于您可能不想手动编写所有内容,od -b
命令可用于生成文件的八进制转储,然后您可以使用一个sed
脚本,用于剥离垃圾并将右侧反斜杠放置到位。