You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust应用中打包静态ELF文件(bubblewrap、bash)

解决方案:将静态ELF嵌入Rust单可执行文件

现成Crate推荐

直接用成熟的crate可以避免手动处理的坑:

  • rust-embed:批量嵌入目录中的文件,支持编译时嵌入,提取逻辑简洁。
  • tempfile:安全创建临时文件,自动管理生命周期,避免手动操作/dev/shm的权限或资源占用问题。

代码示例(rust-embed + tempfile)

  1. 在Cargo.toml添加依赖:
[dependencies]
rust-embed = "6.8.1"
tempfile = "3.8.1"
  1. 编写核心代码:
use rust_embed::RustEmbed;
use std::fs::{self, write};
use std::process::Command;
use tempfile::tempdir;

// 嵌入指定目录下的静态ELF文件(比如bin/bwrap、bin/bash)
#[derive(RustEmbed)]
#[folder = "bin/"]
struct EmbeddedBinaries;

fn main() -> std::io::Result<()> {
    // 创建临时目录,程序退出后自动清理
    let temp_dir = tempdir()?;

    // 提取并执行bubblewrap
    if let Some(bwrap_data) = EmbeddedBinaries::get("bwrap") {
        let bwrap_path = temp_dir.path().join("bwrap");
        write(&bwrap_path, bwrap_data.data)?;
        // 设置可执行权限
        fs::set_permissions(&bwrap_path, fs::Permissions::from_mode(0o755))?;
        
        let output = Command::new(&bwrap_path)
            .arg("--version")
            .output()?;
        println!("bwrap版本: {}", String::from_utf8_lossy(&output.stdout));
    }

    // 提取并执行bash
    if let Some(bash_data) = EmbeddedBinaries::get("bash") {
        let bash_path = temp_dir.path().join("bash");
        write(&bash_path, bash_data.data)?;
        fs::set_permissions(&bash_path, fs::Permissions::from_mode(0o755))?;
        
        let output = Command::new(&bash_path)
            .arg("-c")
            .arg("echo 来自嵌入bash的输出")
            .output()?;
        println!("{}", String::from_utf8_lossy(&output.stdout));
    }

    Ok(())
}

手动实现方案(无需额外Crate)

如果不想依赖第三方crate,需注意规避EBUSY错误:

  • 不要直接对内存映射的文件执行,先解除映射再操作。
  • 写入临时文件后必须设置可执行权限。

示例代码:

use include_bytes;
use std::fs::{self, File};
use std::io::Write;
use std::process::Command;

fn main() -> std::io::Result<()> {
    // 嵌入静态编译的bubblewrap
    let bwrap_bytes = include_bytes!("../static_bin/bwrap");
    
    // 创建临时文件(/tmp目录,也可以用/dev/shm)
    let temp_path = "/tmp/embedded_bwrap";
    let mut temp_file = File::create(temp_path)?;
    temp_file.write_all(bwrap_bytes)?;
    // 设置可执行权限
    fs::set_permissions(temp_path, fs::Permissions::from_mode(0o755))?;
    
    // 执行命令
    let output = Command::new(temp_path)
        .arg("--version")
        .output()?;
    println!("bwrap版本: {}", String::from_utf8_lossy(&output.stdout));
    
    // 可选:程序结束前删除临时文件
    fs::remove_file(temp_path)?;
    
    Ok(())
}

之前EBUSY错误的可能原因

  • 内存映射的文件未解除映射就执行,导致内核锁定文件触发EBUSY。
  • 手动操作/dev/shm时未设置可执行权限,或文件创建后处于占用状态。
  • 直接对内存映射区域执行,而非写入磁盘文件后再调用执行。

内容的提问来源于stack exchange,提问作者viperML

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:02:52