使用std::filesystem::copy复制Ubuntu ISO符号链接到U盘报错如何解决?
错误原因
你遇到的Operation not permitted报错,主要由以下几个常见原因导致:
- 路径参数使用错误:直接传入
/mnt/iso和/mnt/usb调用std::filesystem::copy时,接口会尝试将整个/mnt/iso目录复制到/mnt/usb内部(生成/mnt/usb/iso/...的路径),而非将/mnt/iso下的内容平铺到U盘根目录,如果U盘挂载时没有根目录创建权限就会触发报错。 - 文件系统不兼容符号链接:制作Ubuntu启动盘通常会将U盘格式化为FAT32格式(适配UEFI引导要求),但FAT32本身不支持符号链接,你指定了
copy_options::copy_symlinks参数,遇到符号链接项时就会触发权限类错误。 - 权限不足:ISO挂载后默认通常只有root用户有读取权限,U盘挂载时也可能没有给当前用户开放写入权限,非root运行程序会触发权限不足报错。
修复方案
按以下步骤调整即可解决:
- 调整拷贝逻辑:遍历
/mnt/iso下的所有子文件/子目录,逐个拷贝到/mnt/usb根目录,不要直接拷贝整个源目录。 - 兼容符号链接:如果U盘使用FAT32格式,移除
copy_symlinks参数,改为读取符号链接指向的实际文件内容拷贝到目标路径;如果需要保留符号链接,将U盘分为EFI引导分区(FAT32)和数据分区(ext4等支持符号链接的格式)。 - 提权运行:程序需要使用root权限执行,确保对源和目标目录都有读写权限。
修复后代码示例
#include <filesystem> #include <stdexcept> #include <iostream> namespace fs = std::filesystem; int main() { const fs::path src_dir = "/mnt/iso"; const fs::path dst_dir = "/mnt/usb"; // 前置校验目录合法性 if (!fs::exists(src_dir) || !fs::is_directory(src_dir)) { throw std::runtime_error("源ISO挂载目录不存在或不是目录"); } if (!fs::exists(dst_dir) || !fs::is_directory(dst_dir)) { throw std::runtime_error("目标U盘挂载目录不存在或不是目录"); } const auto base_copy_opt = fs::copy_options::recursive | fs::copy_options::overwrite_existing; // 遍历源目录下所有子项逐个拷贝 for (const auto& entry : fs::directory_iterator(src_dir)) { try { fs::copy(entry, dst_dir / entry.path().filename(), base_copy_opt); } catch (const fs::filesystem_error& e) { // 特殊处理符号链接,拷贝实际指向的文件内容 if (fs::is_symlink(entry.path())) { auto real_src = fs::read_symlink(entry.path()); if (!real_src.is_absolute()) { real_src = src_dir / real_src; } fs::copy(real_src, dst_dir / entry.path().filename(), base_copy_opt); continue; } std::cerr << "拷贝失败: " << entry.path() << ",错误信息: " << e.what() << std::endl; } } return 0; }
额外注意事项
- 如果你的最终目的是制作可引导的Ubuntu安装U盘,更稳妥的方案是直接使用
dd命令将ISO镜像整盘写入U盘,不需要手动拷贝文件,避免丢失引导扇区信息。 - 运行程序前确认ISO已经正确挂载到
/mnt/iso,U盘已经正确挂载到/mnt/usb,且挂载参数没有设置只读属性。
内容的提问来源于stack exchange,提问作者kramer
相关产品推荐
相关产品推荐

