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

C语言实现伪Shell的cp命令:如何处理目标为文件或目录?

C语言伪Shell中cp命令适配目标路径的修改方案

问题背景

当前实现的copyFile函数仅支持目标路径为文件名的场景,需要修改以适配三种目标形式:

  • file:直接将源文件复制为指定文件名
  • dir/file:将源文件复制到指定目录下的指定文件名
  • dir:将源文件复制到指定目录,保留原文件名

修改步骤

1. 添加目录判断逻辑

使用stat函数获取目标路径的文件状态,判断其是否为目录。如果目标路径存在且是目录,需构造新的目标路径(目录+源文件名)。

2. 构造最终目标路径

利用basename函数提取源文件的文件名,拼接在目录路径后形成完整目标路径,自动处理路径末尾是否带/的情况,避免出现dir//file格式错误。

3. 修复原代码缓冲区错误

原代码中char* buff[1024]是指针数组,改为char buff[1024]作为字节缓冲区,避免内存访问异常。

4. 优化权限设置

创建目标文件时继承源文件的权限,贴近系统cp命令的默认行为。

修改后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <libgen.h>

void copyFile(char *sourcePath, char *destinationPath) {
    int srcCheck, destCheck, standardCheck;
    char buff[1024]; // 修复缓冲区类型错误
    struct stat srcStat, destStat;
    char finalDestPath[PATH_MAX];

    // 获取源文件信息(用于权限复制)
    if (stat(sourcePath, &srcStat) < 0) {
        write(1, "Error getting source file info\n", strlen("Error getting source file info\n"));
        return;
    }

    srcCheck = open(sourcePath, O_RDONLY);
    if (srcCheck < 0) {
        write(1, "Error with opening source\n", strlen("Error with opening source\n"));
        return;
    }

    // 判断目标路径是否为目录
    if (stat(destinationPath, &destStat) == 0) {
        if (S_ISDIR(destStat.st_mode)) {
            // 目标是目录,构造最终路径:目录/源文件名
            char *srcBasename = basename(sourcePath);
            snprintf(finalDestPath, sizeof(finalDestPath), "%s/%s", destinationPath, srcBasename);
            destinationPath = finalDestPath;
        }
    }

    // 创建/打开目标文件,使用源文件的权限
    destCheck = open(destinationPath, O_WRONLY | O_CREAT | O_TRUNC, srcStat.st_mode & 0777);
    if (destCheck < 0) {
        close(srcCheck);
        write(1, "Error opening/creating destination\n", strlen("Error opening/creating destination\n"));
        return;
    }

    // 复制文件内容
    while ((standardCheck = read(srcCheck, buff, sizeof(buff))) > 0) {
        if (write(destCheck, buff, standardCheck) != standardCheck) {
            write(1, "Error writing to destination\n", strlen("Error writing to destination\n"));
            close(srcCheck);
            close(destCheck);
            return;
        }
    }

    if (standardCheck == -1) {
        write(1, "Error reading source\n", strlen("Error reading source\n"));
    }

    // 关闭文件描述符
    if (close(srcCheck) == -1) {
        write(1, "Error closing source\n", strlen("Error closing source\n"));
    }
    if (close(destCheck) == -1) {
        write(1, "Error closing destination\n", strlen("Error closing destination\n"));
    }
}

关键说明

  • 通过stat判断目标类型,自动处理目录场景下的路径拼接
  • 修复缓冲区类型错误,解决潜在的内存访问问题
  • 继承源文件权限,保持复制后的文件权限一致性
  • 增加写入错误检测,避免部分写入未被捕获的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:42:05