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

Linux C进程如何等待文件复制完成(无rsync环境)

解决Yocto系统中C程序等待cp命令复制完成的问题

首先得明确一个关键细节:system()函数本身就是阻塞执行的——它会启动shell运行你传入的命令,并且一直等到这个shell进程(包括它启动的cp命令)完全退出后,才会把控制权交还给你的C程序。所以你当前用system("yes | cp -rf ...")的写法,其实程序已经在等待复制完成了,可能你是没正确判断命令是否执行成功?

下面给你几个更可靠的方案,以及如何确认复制完成、处理潜在错误:

1. 正确使用system()并校验执行结果

虽然system是阻塞的,但你需要解析它的返回值来确认cp是否真的执行成功,而不是只等它返回。示例代码:

#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>

int main() {
    const char* cp_cmd = "yes | cp -rf /path/to/local/files /mnt/usb/dest";
    int ret = system(cp_cmd);

    // 解析system的返回值,获取cp命令的真实退出状态
    if (WIFEXITED(ret)) {
        int exit_code = WEXITSTATUS(ret);
        if (exit_code == 0) {
            printf("复制完成且成功!\n");
        } else {
            printf("复制失败,cp命令退出码:%d\n", exit_code);
        }
    } else {
        printf("cp命令被信号中断或异常退出\n");
    }
    return 0;
}

另外可以试试去掉yes |——很多coreutils版本的cp中,-f参数已经会强制覆盖目标文件/目录而不弹出确认提示,这样能减少一个不必要的yes进程,让命令更简洁:

cp -rf /path/to/local/files /mnt/usb/dest

2. 用fork+exec+waitpid实现更可控的纯C方案

如果想完全脱离shell(更符合纯C的需求,也避免shell带来的额外开销和安全风险),可以用fork()创建子进程,在子进程中用execvp()调用cp命令,父进程用waitpid()阻塞等待子进程结束。示例代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>

int main() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork失败");
        return 1;
    } else if (pid == 0) {
        // 子进程:执行cp命令
        char* args[] = {"cp", "-rf", "/path/to/local/files", "/mnt/usb/dest", NULL};
        execvp("cp", args);
        // 如果execvp返回,说明执行失败(正常情况下execvp会替换进程空间,不会返回)
        perror("执行cp命令失败");
        exit(EXIT_FAILURE);
    } else {
        // 父进程:阻塞等待子进程退出
        int status;
        waitpid(pid, &status, 0);

        if (WIFEXITED(status)) {
            int exit_code = WEXITSTATUS(status);
            if (exit_code == 0) {
                printf("复制完成且成功!\n");
            } else {
                printf("复制失败,cp退出码:%d\n", exit_code);
            }
        } else {
            printf("cp进程被信号中断\n");
        }
    }
    return 0;
}

这个方案的优势:

  • 不需要依赖shell,避免了shell解析命令时的潜在问题(比如路径含空格时,system需要额外转义,而exec系列可以直接传参数数组)
  • 能更精准地控制子进程状态,比如后续如果需要非阻塞等待,也能通过修改waitpid的参数实现

3. 额外注意事项

  • 确保USB挂载稳定:复制前一定要确认USB已正确挂载(你之前用popen处理mount的逻辑要保证这一点),否则cp会把文件复制到本地的挂载点目录(而非USB)
  • 大文件/批量文件复制:如果复制内容很大,等待时间会较长,这是正常的,程序会一直阻塞到操作完成
  • 权限与路径校验:复制前最好检查源路径是否存在、目标路径是否有写入权限,避免因为基础问题导致复制失败却没被发现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:49:47