IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux C/C++源码实现常见命令mkdir -> 正文阅读

[系统运维]Linux C/C++源码实现常见命令mkdir

Linux系统是由文件和目录组成的。当我们使用Linux系统时,经常会从中创建目录来保存文件等等,这时会使用Linux自带 mkdir 的命令,用于在操作系统中创建目录或文件夹。在本文中,我们将讨论如何使用带有各种命令行选项的 mkdir 命令以及代码实现。

mkdir命令代码实现

在 Linux 中,虽然 rm 命令允许您删除目录,但首先是 mkdir 命令允许您创建目录。下面我们实现mkdir命令:

#include <stdio.h>
#include <sys/types.h> /*umask、stat*/
#include <sys/stat.h> /*chmod*/
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include <libgen.h> /*dirname*/
#include <stdlib.h>
#include <string.h>

/*
	int mkdir(const char *pathname, mode_t mode);
	mode方式:
	S_IRWXU 	00700权限,代表该文件所有者拥有读,写和执行操作的权限
	S_IRUSR(S_IREAD) 	00400权限,代表该文件所有者拥有可读的权限
	S_IWUSR(S_IWRITE) 	00200权限,代表该文件所有者拥有可写的权限
	S_IXUSR(S_IEXEC) 	00100权限,代表该文件所有者拥有执行的权限
	S_IRWXG 	00070权限,代表该文件用户组拥有读,写和执行操作的权限
	S_IRGRP 	00040权限,代表该文件用户组拥有可读的权限
	S_IWGRP 	00020权限,代表该文件用户组拥有可写的权限
	S_IXGRP 	00010权限,代表该文件用户组拥有执行的权限
	S_IRWXO 	00007权限,代表其他用户拥有读,写和执行操作的权限
	S_IROTH 	00004权限,代表其他用户拥有可读的权限
	S_IWOTH 	00002权限,代表其他用户拥有可写的权限
	S_IXOTH 	00001权限,代表其他用户拥有执行的权限

*/

/*
	参数 mode 有下列数种组合:
	S_ISUID 04000 文件的 (set user-id on execution)位
	S_ISGID 02000 文件的 (set group-id on execution)位
	S_ISVTX 01000 文件的sticky 位
	S_IRUSR (S_IREAD) 00400 文件所有者具可读取权限
	S_IWUSR (S_IWRITE)00200 文件所有者具可写入权限
	S_IXUSR (S_IEXEC) 00100 文件所有者具可执行权限
	S_IRGRP 00040 用户组具可读取权限
	S_IWGRP 00020 用户组具可写入权限
	S_IXGRP 00010 用户组具可执行权限
	S_IROTH 00004 其他用户具可读取权限
	S_IWOTH 00002 其他用户具可写入权限
	S_IXOTH 00001 其他用户具可执行权限
	
*/


static int	vflag;

static void usage(void)
{
	(void)fprintf(stderr,"usage: mkdir [-pv] [-m mode] directory_name ...\n");
}


/*
 *对于一个a/b/c这样的一个多级目录,要想实现父目录的创建方法,
 可以进行字符串处理分出一级一级目录.
 * 成功完成后,mkdir() 应返回 0。否则,应返回 -1,不应创建目录,并应设置 errno 以指示错误。 
 */

static int create_directory(char *path, mode_t omode)
{
	struct stat sb;
	mode_t numask, oumask;
	int first, last, retval;
	char *p;
	/*检查我们是否需要对中间目录做任何事情*/
	p = path;
	oumask = 0;
	retval = 1;
	if (p[0] == '/')		/* Skip  '/'. */
		++p;
	for (first = 1, last = 0; !last ; ++p) {
		if (p[0] == '\0')
			last = 1;
		else if (p[0] != '/')
			continue;
		*p = '\0';
		if (!last && p[1] == '\0')
			last = 1;
		if (first) {
			oumask = umask(0);
			numask = oumask & ~(S_IWUSR | S_IXUSR);
			(void)umask(numask);
			first = 0;
		}
		if (last)
			(void)umask(oumask);
		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
			if (errno == EEXIST || errno == EISDIR) {
				/*
					判断该文件或目录是否否存在 ;得到st_mode,然后判断是不是目录文件。
					成功判断返回的st_mode是否是一个文件夹。
				*/
				if (stat(path, &sb) < 0) {
					warn("%s", path);
					retval = 0;
					break;
				} else if (!S_ISDIR(sb.st_mode)) {
					if (last)
						errno = EEXIST;
					else
						errno = ENOTDIR;
					warn("%s", path);
					retval = 0;
					break;
				}
				if (last)
					retval = 2;
			} else {
				warn("%s", path);
				retval = 0;
				break;
			}
		} else if (vflag)
			printf("%s\n", path);
		if (!last)
		    *p = '/';
	}
	if (!first && !last)
		(void)umask(oumask);
	return (retval);
}



int main(int argc, char *argv[])
{
	int ch, exitval, success, pflag;
	mode_t omode;
	void *set = NULL;
	char *mode;

	omode = pflag = 0;
	mode = NULL;
	while ((ch = getopt(argc, argv, "m:pv")) != -1)
		switch(ch) {
		case 'm':
			mode = optarg;
			break;
		case 'p':
			pflag = 1;
			break;
		case 'v':
			vflag = 1;
			break;
		case '?':
		default:
			usage();
		}

	argc -= optind;
	argv += optind;
	if (argv[0] == NULL)
		usage();

	if (mode == NULL) {
		omode = S_IRWXU | S_IRWXG | S_IRWXO;
	}

	for (exitval = 0; *argv != NULL; ++argv) {
		if (pflag) {
			success = create_directory(*argv, omode);
		} else if (mkdir(*argv, omode) < 0) {
			if (errno == ENOTDIR || errno == ENOENT)
				warn("%s", dirname(*argv));
			else
				warn("%s", *argv);
			success = 0;
		} else {
			success = 1;
			if (vflag)
				(void)printf("%s\n", *argv);
		}
		if (!success)
			exitval = 1;
		/*
		 chmod()会依参数mode 权限来更改参数path 指定文件的权限。
		 */
		if (success == 1 && mode != NULL && chmod(*argv, omode) == -1) {
			warn("%s", *argv);
			exitval = 1;
		}
	}
	return (exitval);
}

编译运行:

在这里插入图片描述my_mkdir将创建一个名为 path 的新目录。 新目录的文件权限位应从模式初始化。 mode 参数的这些文件权限位应由进程的文件创建掩码修改。

mkdir代码时候很简单, 主要用于在我们的 Linux 操作系统中创建目录。居然代码实现能创建目录,我们接下来使用选项看看效果。

创建多目录

当我们需要创建多目录时,只需要命名我们要创建的目录。这里需要注意一下,我们需要给目录名称加上空格以创建多个目录。 可以使用以下命令:

./my_mkdir aaa bbb ccc

在这里插入图片描述

创建父目录

./my_mkdir a/b

上面的命令将在目录 a 中创建名为 b 的目录。 如果目录 a 不存在,则会显示错误消息。

在这里插入图片描述

如果父目录不存在,则使用 –p 选项将创建它。

在这里插入图片描述

如果目录a不存在,mkdir命令将创建目录a,并在目录a内创建一个名为b的目录。

如何在详细模式下创建目录?

我们可以使用 –v 选项以详细模式创建新目录。 当您使用此选项创建新目录时,它将在屏幕中生成以下详细输出。 在这里插入图片描述

总结

以代码实现mkdir命令,然后将 mkdir 与各种命令行选项结合使用。本篇可以看到 mkdir 是一个非常简单的命令,可以很好的理解和使用。

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792)交流学习。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:21:05  更:2021-09-01 12:22:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 11:38:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码