关注领取运维自学路线资料 | 进百人交流群

在我们安装某类产品时,可以发现他们安装脚本中存在一个二进制文件,这个二进制文件无法打开保密性很强。你有没有对此很好奇,这是通过什么方法实现的?

今天我们来看一个例子,在安装 PandaWiki 时,提供了一个安装命令。这个安装命令下载了一个 Shell 脚本文件,于是我将其手动下载下来了。

#!/bin/bash# 设置颜色输出RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m'# No Color# 设置错误处理set -etrap'handle_error $? $LINENO' ERR# 错误处理函数handle_error() {local exit_code=$1local line_number=$2echo -e "${RED}Error occurred in script at line $line_number with exit code $exit_code${NC}" cleanupexit$exit_code}# 清理函数cleanup() {echo -e "${YELLOW}Cleaning up temporary files...${NC}" rm -f "$FILE_NAME"}# 检查系统架构ARCH=$(uname -m)case"$ARCH"in"x86_64"|"amd64") ARCH="x86_64" ;;"aarch64"|"arm64"|"armv8l") ARCH="aarch64" ;; *)echo -e "${RED}This installer only supports amd64 (x86_64) and arm64 (aarch64) architectures${NC}"echo -e "${RED}Current architecture: $ARCH${NC}"exit 1 ;;esac# 检查root权限if [[ $EUID -ne 0 ]]; thenecho -e "${RED}This script must be run as root${NC}"exit 1fiecho -e "${GREEN}Architecture: $ARCH${NC}"# 设置变量if [[ "$ARCH" == "x86_64" ]]; then URL="https://release.baizhi.cloud/panda-wiki/installer_amd64"elif [[ "$ARCH" == "aarch64" ]]; then URL="https://release.baizhi.cloud/panda-wiki/installer_arm64"fiFILE_NAME="/tmp/panda-wiki-installer"echo -e "${GREEN}Starting Panda Wiki Installer${NC}"echo -e "${YELLOW}Downloading installer...${NC}"# 下载安装程序if ! curl -4sSLk -o "$FILE_NAME""$URL"; thenecho -e "${RED}Failed to download installer${NC}"exit 1fiecho -e "${GREEN}Download completed${NC}"echo -e "${YELLOW}Setting up installer...${NC}"# 设置执行权限chmod +x "$FILE_NAME"echo -e "${GREEN}Starting installation...${NC}"# 执行安装程序if ! $FILE_NAME; thenecho -e "${RED}Installation failed${NC}" cleanupexit 1fiecho -e "${GREEN}Installation completed successfully${NC}"cleanupexit 0脚本中设置变量处有一个 url 地址(https://release.baizhi.cloud/panda-wiki/installer_amd64)下载了一个installer_amd64文件,这个文件就是 PandaWiki 的安装程序,也是被称为一个二进制文件。这种一般是怎么实现的?运行环境是啥?这个二进制文件为啥可以直接执行呢?
这个 installer_amd64 文件通常是由 Go 语言 (Golang) 或 Rust 等编译型语言编写的。
GOOS=linux GOARCH=amd64 go build),将源代码直接编译成了 Linux 系统下的机器码。amd64 明确指出了它是为 64位 x86 架构(即常见的 Intel 或 AMD 服务器/PC CPU)编译的。它的运行环境非常简单,只需要操作系统内核的支持,不需要额外的解释器。
x86_64 (amd64) 或 aarch64 (arm64) 架构的 CPU。这也是为什么脚本开头要先用 uname -m 检查架构的原因。如果架构不匹配,二进制文件是无法运行的。chmod +x)。这是它与 Shell 脚本最大的区别。Shell 脚本(如你贴出的这段代码)是“解释执行”的,需要 /bin/bash 来一行行翻译;而二进制文件是“直接执行”的。
具体原因如下:

要打包生成像 installer_amd64 这样的单文件二进制可执行程序,最主流、最成熟的方案是使用 Go 语言 (Golang) 进行静态编译。
虽然 Python 或 C++ 也能做到,但在云原生和运维工具领域(比如 Kubernetes、Docker、Terraform 等),Go 是绝对的首选,因为它能极其方便地将所有依赖“打包”进一个文件里。
以下是实现这种打包的具体步骤和原理:
所谓的“打包”,在 Go 语言中其实就是编译。 普通的程序(动态链接)运行时需要依赖操作系统的库(如 .so 或 .dll 文件)。 而你要的 installer_amd64 是通过静态链接编译的,它把运行所需的所有代码(包括标准库、第三方库)都“缝合”进了这一个文件里,所以它不需要任何外部环境就能跑。
假设你写好了一个安装程序的代码(比如叫 main.go),你想把它变成那个 installer_amd64 文件,你需要这样做:
你需要安装 Go 语言环境。
写一个简单的 main.go(这只是个示例,实际的安装程序逻辑会复杂得多):
package mainimport"fmt"funcmain() { fmt.Println("Hello, I am the installer!")// 这里会有解压文件、写入配置、启动服务等复杂逻辑}这是生成你看到的那个文件的魔法命令。你需要设置环境变量来指定目标平台,并使用标志位开启静态编译。
在终端中执行:
# 设置目标操作系统为 Linuxexport GOOS=linux# 设置目标架构为 AMD64 (即 x86_64)export GOARCH=amd64# 禁用 CGO (C语言接口),这是实现“纯静态编译”的关键,确保不依赖系统的 glibcexport CGO_ENABLED=0# 编译并输出文件# -ldflags "-s -w" 用于去除调试信息,减小文件体积go build -ldflags "-s -w" -o installer_amd64 main.go命令解释:
GOOS=linux:告诉编译器,我要生成 Linux 下能跑的程序(即使你在 Windows 或 Mac 上运行这个命令也可以)。GOARCH=amd64:告诉编译器,目标机器是 64 位 Intel/AMD 架构。CGO_ENABLED=0:这是最重要的一步。它强制 Go 编译器不要依赖系统的 C 库。这样生成的文件才是真正独立的,扔到任何 Linux 发行版(CentOS, Ubuntu, Debian)上都能直接运行。-o installer_amd64:指定输出的文件名。虽然你之前的搜索结果里提到了 PyInstaller,但 PyInstaller 打包出来的通常是一个文件夹(包含 python 解释器、各种 .so 库文件),或者是一个巨大的自解压包。
如果你的安装程序需要释放一些额外的文件(比如配置文件模板、静态网页资源),你不需要让用户下载一堆文件。你可以使用 Go 的 **embed** 功能,把这些文件直接编译进二进制里。
代码示例:
package mainimport ( _ "embed"// 引入 embed 包"fmt""os")//go:embed config.yaml <-- 魔法在这里,把文件内容直接读入变量var configFile []bytefuncmain() {// 程序运行时,直接把内存里的 configFile 写入到硬盘 os.WriteFile("/etc/myapp/config.yaml", configFile, 0644) fmt.Println("配置文件已释放!")}关注领取运维自学路线资料 | 进百人交流群

个人博客:博客介绍
进百人交流群(推荐vx群聊):运维交流/商务合作,集合

