java - 在 shell 脚本中嵌入可执行二进制文件

标签 java c shell binary

首先,我已经用谷歌搜索了,但只找到了将压缩文件(例如 .tar.gz)嵌入到 shell 脚本中的示例。

基本上,如果我有一个打印字符串的 C 程序 (hello.c),比如 Hello World!

我编译它得到一个可执行的二进制文件

gcc hello.c -o hello

现在我有一个 shell 脚本 testEmbed.sh

我想问的是是否可以将二进制文件 (hello) 嵌入到 shell 脚本中,以便在我运行时

./testEmbed.sh

它执行二进制文件打印Hello World!

澄清: 一种替代方法是将可执行文件压缩到存档中,然后在脚本运行时将其解压缩。我想问的是,如果没有它,是否可以运行该程序。

到目前为止,我一直在尝试 here 方法.但这对我不起作用。我猜作者在另一种架构上使用了其他发行版。所以,基本上这对我不起作用。 :P

此外,如果 C 程序的工作流程与 Java jar 不同,我也想知道!

最佳答案

是的,这是可以做到的。它在概念上实际上与您的链接文章非常相似。诀窍是使用 uuencode 将二进制文件编码为文本格式,然后将其附加到脚本的末尾。

然后您的脚本以这样的方式编写,它在自身上运行 uudecode 以创建一个二进制文件,更改权限然后执行它。

uuencodeuudecode 最初是为了将二进制内容转移到互联网的前身而创建的,而互联网并不能很好地处理二进制信息。转换为文本意味着它也可以作为 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 在其输入(beginend)中查找某些标记行,这些标记行由 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

关于java - 在 shell 脚本中嵌入可执行二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10491704/

相关文章:

c - 在 `if` 条件下将变量赋值为零时会发生什么?

linux - 时间通过领先的 sudo 调用产生奇怪的结果

java - 如何在android中使用java在mysql数据库中保存值

java - 如何在 Eclipse 中将 Java 项目更改为 gwt Web 应用程序?

Java试图捕获非整数用户输入并使其循环

java - 在 Pig 中使用 AvroStorage()

c - 优化设置

Python-C api并发问题

bash - 在bash数组中循环使用docker命令的参数?

linux - 剥离错误或没有错误