自定义linux cp命令

2023-09-21 16:01:03

基本要求:


1.基本要求,实现文件的复制。编写程序实现cp命令的功能,程序源文件名为mycp.c,使用方法为:

./mycp 源文件名 目标文件名

2.扩展要求,当目标文件已存在时,给出提示是否进行覆盖,并根据用户的回应进行相应的操作。

3.扩展要求,在上一步实现功能的基础上,为mycp增加选项,如果选项为-f,则当目标文件已存在时,不发出提示信息。

实现程序:


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

#define ssize_t long long

int main(int argc, char *argv[])
{
    // 基本要求:检查命令行参数
    if (argc < 3)
    {
        fprintf(stderr, "wrong usage! you shoule input like:\n.\\mycp sourceFileName destinationFileName [-f]");
        exit(1);
    }

    char *source_file = argv[1];
    char *destination_file = argv[2];
    // 1. 首先判断文件是否存在
    int alreadyExist = access(destination_file, F_OK); /* access函数的作用,第二个参数可以是
                                                        R_OK 判断文件是否可读
                                                        W_OK 判断文件是否可写
                                                        X_OK 判断文件是否可执行
                                                        F_OK 判断文件是否存在
                                                        返回0则表示条件成立,-1则表示条件不成立
                                                        */
    // 2. 判断有没有-f参数
    int force = (argc == 4 && strcmp(argv[3], "-f") == 0) ? 1 : 0;
    // 3. 没有-f参数又已经存在文件则提示需不需要覆盖
    if (!force && !alreadyExist)
    {
        char response[10];
        printf("The destinationFile has existed!\nDo you want to overwirte the original file?(y/n): ");
        fgets(response, sizeof(response), stdin);
        /*
        从第三个参数指定的流中读取最多第二个参数大小的字符到第一个参数指定的容器地址中。
        在这个过程中,在还没读取够第二个参数指定大小的字符前,读取到换行符'\n'或者需要读取的流中已经没有数据了。
        则提前结束,并把已经读取到的字符存储进第一个参数指定的容器地址中。
        */
        if (response[0] != 'y' && response[0] != 'Y')
        {
            printf("exit.\n");
            return 0;
        }
    }
    // 4. 开始复制文件
    //  打开源文件
    int src_fd = open(source_file, O_RDONLY);
    if (src_fd == -1)
    {
        fprintf(stderr, "can't open the source_file!\n");
        exit(1);
    }

    int dest_fd = open(destination_file, alreadyExist ? O_WRONLY | O_CREAT : O_WRONLY | O_TRUNC);
    /*
        如果alreadExist为1,即文件不存在,则创建文件
        如果alreadExist为0,即文件存在,则覆盖文件
    */
    if (dest_fd == -1)
    {
        fprintf(stderr, "can't make the destination_file!\n");
        close(src_fd);
        exit(1);
    }
    int size = filelength(src_fd);
    if (size > 10000)
    {
        fprintf(stderr, "the file is too large to cp!\n");
        close(src_fd);
        close(dest_fd);
        exit(1);
    }
    // 读取源文件并写入目标文件

    char buffer[10000];
    ssize_t bytes_read;
    while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0)
    {
        if (write(dest_fd, buffer, bytes_read) != bytes_read)
        {
            fprintf(stderr, "write error!\n");
            close(src_fd);
            close(dest_fd);
            exit(1);
        }
    }

    // 关闭文件描述符
    close(src_fd);
    close(dest_fd);

    printf("successfully cp!\n");

    return 0;
}

在使用gcc -o mycp mycp.c编译生成 .exe 文件之后即可以正常使用

功能比较拉胯,仅供图一乐。

需要注意的是windows命令行默认的是GBK编码,所以代码内容最好不要有中文,不然会出现乱码

更多推荐

Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)

Vue3实现一个无缝滚动组件(支持鼠标手动滚动)前言在日常开发中,经常遇到需要支持列表循环滚动展示,特别是在数据化大屏开发中,无缝滚动使用频率更为频繁,在jquery时代,我们常用的无缝滚动组件为liMarquee,在vue中已经有vue-seamless-scroll组件(通过Vue2实现,不支持鼠标手动滚动),但是

LeetCode算法递归类—剑指 Offer 26. 树的子结构

目录剑指Offer26.树的子结构题解:代码:运行结果:​编辑输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)B是A的子结构,即A中有出现和B相同的结构和节点值。例如:给定的树A:3/\45/\12给定的树B:4/1返回true,因为B与A的一个子树拥有相同的结构和节点值。示例1:输入:

10个强大的 JavaScript 动画库、直接抄作业

动画,是吸引你客户注意的好方法之一。在项目开发中,我们可以通过创造有趣的动画来为我们的项目增加视觉感与用户体验,同时,也为我们的网站增添了独特的美感,而且还提高了用户参与度并创造了令人难忘的第一印象。因此,今天这篇文章,我将整理了10个有趣又有用的JavaScript动画库,从而帮助你快速创建动画,其中包括,滚动动画、

基于Hadoop的豆瓣电影的数据抓取、数据清洗、大数据分析(hdfs、flume、hive、mysql等)、大屏可视化

目录项目介绍研究背景国内外研究现状分析研究目的研究意义研究总体设计数据获取网络爬虫介绍豆瓣电影数据的采集数据预处理数据导入及环境配置Flume介绍Hive介绍MySQL介绍Pyecharts介绍环境配置及数据加载大数据分析及可视化豆瓣影评结构化分析豆瓣电影类型占比分析豆瓣电影导演排行榜分析不同国家的电影数据分析电影演员

PostgreSQL 主从复制&故障切换

文章目录前言环境准备搭建主从节点配置主从节点从节点加入主节点查看主从信息主从故障切换前言PostgreSQL的主从复制是一种非常简单且常用的高可用性和可扩展性解决方案,本质上是将主服务器的数据复制到一个或多个从服务器上,从而提高系统的性能和可靠性,并提供数据备份和故障恢复的能力。环境准备搭建主从节点准备两个节点,一主一

@Deprecated

@Deprecated是一个Java中的注解,用于指示某个类、方法、字段或者其他程序元素已经被废弃不再建议使用。使用@Deprecated注解可以向其他开发者传达这个元素已经过时,不推荐使用,并提醒他们使用其他替代的方案。通常情况下,当一个类、方法、字段或者其他程序元素被@Deprecated注解标记之后,编译器会在使

知识图谱基本工具Neo4j使用笔记 五 :APOC插件安装及简单应用

文章目录一、使用场景二、系统说明三、配置安装1.插件下载2.文件下载说明3.版本对应4.安装位置5.修改配置文件6.注意问题7.web端启动:测试四、简单应用1.编辑距离2.基于编辑距离的相似度3.模糊匹配一、使用场景APOC(AwesomeProceduresonCypher)是Neo4j图数据库的一个插件,它提供了

SOLIDWORKS2024新功能--SOLIDWORKS篇(二)

该章节包括以下主题:切口工具槽口延伸戳记工具薄片和槽口中的切割法线切口工具您可以使用切口工具在空心或薄壁圆柱体和圆锥体中生成切口。通过选择圆柱面或圆锥面上的边线,您可以将零件平展为钣金。在早期版本中,如果您有圆柱形或圆锥形零件,则必须在基本草图中有意生成间隙才能将零件转换为钣金。SOLIDWORKS仅支持直线切断,不支

文盘Rust -- tonic-Rust grpc初体验 | 京东云技术团队

gRPC是开发中常用的开源高性能远程过程调用(RPC)框架,tonic是基于HTTP/2的gRPC实现,专注于高性能、互操作性和灵活性。该库的创建是为了对async/await提供一流的支持,并充当用Rust编写的生产系统的核心构建块。今天我们聊聊通过使用tonic调用grpc的的具体过程。工程规划rpc程序一般包含s

zabbix自定义监控、钉钉、邮箱报警 (五十六)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档目录一、实验准备二、安装三、添加监控对象四、添加自定义监控项五、监控mariadb1、添加模版查看要求2、安装mariadb、创建用户3、创建用户文件4、修改监控模版5、在上述文件中配置路径6、重启zabbix-agent验证六、监控NGINX1、安装NG

干货!网络丢包故障定位全景指南

极客星球:深入理解网络子系统欢迎加入极客星球,一起学习,快速成长:修炼基本功,打好高薪基础:分享基础技术深度理解,基础概念深度解析,经典书籍推荐和读书分享,经典源码阅读分享等,不定期直播分享,问题答疑解惑;扩展技术深度和技术视野:分享热门技术发展,国内外大厂技术内幕,业界解决方案;校招/社招免费就业指导:模拟面试,简历

热文推荐