Linux 使用C语言删除一个非空的目录

文章目录

  • 一、简介
  • 二、代码演示

一、简介

Linux 下可以使用 rmdir 系统调用来删除一个目录,但是只能删除一个非空目录。

NAMErmdir - delete a directorySYNOPSIS#include <unistd.h>int rmdir(const char *pathname);DESCRIPTIONrmdir() deletes a directory, which must be empty.

在 shell命令行我们用 rm -rf 来删除一个目录,那我们仿照 rm -rf 的原理来实现一个使用C语言删除一个非空的目录。

当执行 rm -rf 命令时,它会按照以下步骤进行操作:

首先,命令会尝试打开指定的目录 <directory>。
如果成功打开目录,命令会遍历目录中的所有子目录和文件。
对于每个子目录和文件,命令会递归调用自身,以便删除子目录和文件。
如果遇到子目录,将按照相同的步骤递归删除子目录及其内容。
如果遇到文件,命令将直接删除文件。
删除完成后,命令关闭目录。

(1)使用 tree 命令查看目录结构:

# tree dir_test/
dir_test/
├── 3.txt
├── 4.txt
├── 5.txt
└── dir1├── 1.txt└── 2.txt1 directory, 5 files

(2)使用 strace 来 追踪 rm -rf 命令:

[root@localhost c_test]# strace -e trace=file rm -rf dir_test/
execve("/usr/bin/rm", ["rm", "-rf", "dir_test/"], 0x7ffe2a252c50 /* 27 vars */) = 0
......
newfstatat(AT_FDCWD, "dir_test/", {st_mode=S_IFDIR|0755, st_size=57, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(AT_FDCWD, "dir_test/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = 3
openat(AT_FDCWD, "dir_test/", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = 3
newfstatat(4, "dir1", {st_mode=S_IFDIR|0755, st_size=32, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(4, "dir1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = 3
openat(4, "dir1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY) = 3
unlinkat(5, "1.txt", 0)                 = 0
unlinkat(5, "2.txt", 0)                 = 0
unlinkat(4, "dir1", AT_REMOVEDIR)       = 0
unlinkat(4, "3.txt", 0)                 = 0
unlinkat(4, "4.txt", 0)                 = 0
unlinkat(4, "5.txt", 0)                 = 0
unlinkat(AT_FDCWD, "dir_test/", AT_REMOVEDIR) = 0

主要是:

unlinkat(5, "1.txt", 0)                 = 0
unlinkat(5, "2.txt", 0)                 = 0
unlinkat(4, "dir1", AT_REMOVEDIR)       = 0
unlinkat(4, "3.txt", 0)                 = 0
unlinkat(4, "4.txt", 0)                 = 0
unlinkat(4, "5.txt", 0)                 = 0
unlinkat(AT_FDCWD, "dir_test/", AT_REMOVEDIR) = 0

可以看到删除一个目录,首先将该目录下的文件删除掉,然后再删除掉该空目录。

二、代码演示

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <limits.h>void removeDirectory(const char* dirPath) {struct stat st;if (lstat(dirPath, &st) == -1) {perror("lstat");return;}if (S_ISDIR(st.st_mode)) {DIR* dir = opendir(dirPath);if (dir == NULL) {perror("opendir");return;}char path[PATH_MAX];struct dirent* entry;while ((entry = readdir(dir)) != NULL) {if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {continue;}snprintf(path, sizeof(path), "%s/%s", dirPath, entry->d_name);removeDirectory(path);}closedir(dir);if (rmdir(dirPath) == -1) {perror("rmdir");return;}printf("Directory %s deleted successfully.\n", dirPath);} else if (S_ISREG(st.st_mode)) {if (remove(dirPath) == -1) {perror("remove");return;}printf("File %s deleted successfully.\n", dirPath);} else {printf("%s is of unknown file type.\n", dirPath);}
}int main(int argc, char* argv[]) {if (argc != 2) {printf("Usage: %s <file_path>\n", argv[0]);return 1;}const char* filePath = argv[1];removeDirectory(filePath);return 0;
}
# ./a.out dir_test/
File dir_test//dir1/1.txt deleted successfully.
File dir_test//dir1/2.txt deleted successfully.
Directory dir_test//dir1 deleted successfully.
File dir_test//3.txt deleted successfully.
File dir_test//4.txt deleted successfully.
File dir_test//5.txt deleted successfully.
Directory dir_test/ deleted successfully.
unlinkat(5, "1.txt", 0)                 = 0
unlinkat(5, "2.txt", 0)                 = 0
unlinkat(4, "dir1", AT_REMOVEDIR)       = 0
unlinkat(4, "3.txt", 0)                 = 0
unlinkat(4, "4.txt", 0)                 = 0
unlinkat(4, "5.txt", 0)                 = 0
unlinkat(AT_FDCWD, "dir_test/", AT_REMOVEDIR) = 0

可以看到和 rm -rf 命令删除非空目录过程相同。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Proxmox VE 实现批量增加多网络

前言 实现批量创建多网络&#xff0c;更改主机名称&#xff0c;hosts解析 初始化网卡&#xff0c;主机名称&#xff0c;hosts解析&#xff0c;重启网卡 我的主机六个网卡&#xff0c;使用的有四个网卡&#xff0c;以下一键创建和初始化主机名称我是以硬件的SN号最为主机的名…

Matlab调C/C++简单模板例子

如果你是需要快速搭建一个matlab调c/c环境&#xff0c;这篇文章可以参考 有了c代码&#xff0c;想在matlab里面调用&#xff0c;可以参考我这个模板 matlab调用代码&#xff1a; clear all close all clcinput1 1; input2 2;[output1,output2] mexfunction(input1,input2);…

普通人做抖音小店真的能赚钱吗?可以,但更取决于个人

大家好&#xff0c;我是电商花花。 现在做抖音小店的基本上都是一些新商家&#xff0c;对于我们众多零基础的朋友来说&#xff0c;是期待也是一份挑战。 抖音小店作为一个充满机会的新兴平台&#xff0c;许多人都欣喜的投入其中&#xff0c;期望能够借此来改变自己的命运&…

西门子电动阀门

一、西门子电动调节阀 二、西门子电动调节蝶阀 1、阀门 2、执行器

客户资料不翼而飞?企业数据保护攻略

在数字化经济时代&#xff0c;企业的客户资料等同于商业生命线&#xff0c;一旦泄露&#xff0c;后果不堪设想。例如&#xff0c;2017年Equifax的数据泄露事件&#xff0c;造成超过1.4亿用户的个人信息外泄&#xff0c;不仅给用户带来风险&#xff0c;也让公司名誉受损&#xf…

BackTrader 中文文档(二)

原文&#xff1a;www.backtrader.com/ 概念 平台概念 原文&#xff1a;www.backtrader.com/docu/concepts/ 这是平台某些概念的集合。它试图收集可在使用平台时有用的信息片段。 开始之前 所有小代码示例都假设以下导入可用&#xff1a; import backtrader as bt import ba…

移植speexdsp到OpenHarmony标准系统④

五、在OpenHarmony编译体系下增量编译Speexdsp 建议先增量编译生成三方库的动态链接库和可执行文件,验证是否成功把三方库加入OpenHarmonybian编译体系。 成功编译出so和可执行文件&#xff0c;即成功把三方库加入到ohos编译体系。之后还要验证三方库在ohos运行&#xff0c;功…

英语新概念2-回译法-lesson8

乔桑德斯有着我们镇上最漂亮的花园。附近的每一个人每年都参加“最美花园比赛”&#xff0c;但是每年都是乔赢得比赛。比尔芙丽丝的花园比乔的花园大&#xff0c;但是乔的花园更有趣。他有整洁的小径以及一座木桥架在一个池塘上。我也喜欢花园&#xff0c;但是我不喜欢辛勤劳作…

企业网络日益突出的难题与SD-WAN解决方案

随着企业规模的迅速扩张和数字化转型的深入推进&#xff0c;企业在全球范围内需要实现总部、分支机构、门店、数据中心、云等地点的网络互联、数据传输和应用加速。SD-WAN作为当今主流解决方案&#xff0c;在网络效率、传输质量、灵活性和成本等方面远远超越传统的互联网、专线…

【经典算法】LeetCode 136:只出现一次的数字(Java/C/Python3实现含注释说明,Easy)

个人主页&#xff1a; 进朱者赤 阿里非典型程序员一枚 &#xff0c;记录平平无奇程序员在大厂的打怪升级之路。 一起学习Java、大数据、数据结构算法&#xff08;公众号同名&#xff09; 目录 题目描述思路及实现方式一&#xff1a;使用异或运算&#xff08;推荐&#xff09;思…

【论文笔记 | 异步联邦】Asynchronous Federated Optimization

论文信息 Asynchronous Federated Optimization&#xff0c;OPT2020: 12th Annual Workshop on Optimization for Machine Learning&#xff0c;不属于ccfa introduction 背景&#xff1a;联邦学习有三个关键性质 任务激活不频繁&#xff08;比较难以达成条件&#xff09;&…

C++ ─── 操作符重载和赋值重载

目录 赋值运算符重载 运算符重载 赋值运算符重载&#xff08;赋值重载operator&#xff09; 前置和后置重载 赋值运算符重载 运算符重载 C为了增强代码的可读性引入了运算符重载 &#xff0c; 运算符重载是具有特殊函数名的函数 &#xff0c;也具有其返回值类型&#xff0c…

某手滑块逆向流程分析

声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 aHR0cHM6Ly93d3cua3VhaXNob3UuY29tL3Byb2ZpbGUvM3h4Ymt3ZDhta250ZWFj 参数流程…

开发工具:推荐一款实用的浏览器查看json插件(附下载)

目录 插件简介 支持的 mime类型 插件特点 “Tree”视图支持的快捷键列表: “Code”视图支持的快捷键列表: 安装方法 使用效果 插件简介 “JSON Beautifier”扩展程序是一个实用工具&#xff0c;可方便查看、编辑、格式化、验证和导出JSON页面。该扩展程序无需任何设置即可运行…

# Nacos 服务发现-Spring Cloud Alibaba 综合架构实战(四) -实现 service2 子模块。

Nacos 服务发现-Spring Cloud Alibaba 综合架构实战&#xff08;四&#xff09; -实现 service2 子模块。 1、在 service2 子模块下的 service-2-api 二级子工程中&#xff0c;定义服务接口 创建 ProviderService.java /*** C:\java-test\idea2019\nacos_discovery\nacos-mi…

【Java开发指南 | 第三篇】Java 空行、强制类型转换及基本数据类型

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 Java 空行强制类型转换Java 基本数据类型内置数据类型引用类型 Java 空行 空白行或者有注释的行&#xff0c;Java 编译器都会忽略掉。 强制类型转换 当需要将一个数据类型转换为另一个数据类型时&#xff0c…

Cat6 屏蔽与非屏蔽:决定最佳选择

Cat6 电缆通常用于现代网络中的高速以太网数据传输。它们有两种类型&#xff1a;屏蔽 &#xff08;STP&#xff09; 和非屏蔽 &#xff08;UTP&#xff09;。这两种电缆之间的主要区别在于它们对电磁干扰 &#xff08;EMI&#xff09; 和串扰的抵抗力。 屏蔽 Cat6 电缆具有额外…

python代码打包exe文件

创建和激活虚拟环境 创建虚拟环境 首先让我们创建一个虚拟环境。你可以使用 venv 模块来创建一个虚拟环境。以下是创建虚拟环境的步骤&#xff1a; 打开终端&#xff08;或命令提示符&#xff09;&#xff1a;进入你想要创建虚拟环境的目录。 运行以下命令来创建虚拟环境&a…

谷歌pixel6/7pro等手机WiFi不能上网,显示网络连接受限

近期在项目中遇到一个机型出现的问题,先对项目代码进行排查,发现别的设备都能正常运行,就开始来排查机型的问题,特意写出来方便后续查看,也方便其它开发者来自查。 设备机型:Pixel 6a 设备安卓版本:13 该方法无需root,只需要电脑设备安装adb(即Android Debug Bridge…

protobuf 编码原理

简介 Protocol Buffers&#xff08;protobuf&#xff09;&#xff0c;它是 Google 开发的一种数据序列化协议&#xff08;与 XML、JSON 类似&#xff09;。 优点&#xff1a; 效率高&#xff1a;Protobuf 以二进制格式存储数据&#xff0c;比如 XML 和 JSON 等文本格式更紧凑…