在Linux系统中,mkdir是一条用于创建目录的基础命令。当我们执行mkdir时,表面看只是多出了一个文件夹,实际上它触发了从用户态到内核态的一系列调用,最终由文件系统完成元数据与数据块的分配。理解这条命令背后的执行逻辑,对排查目录创建失败、理解磁盘占用都有直接帮助。

mkdir命令的用户态流程
我们在shell中输入mkdir mydir,首先由shell解析命令并启动一个进程,该进程会调用C库中的mkdir函数。这个函数并不是由shell自己实现目录创建,而是通过软中断进入内核。在glibc中,mkdir函数通常会封装系统调用mkdir或mkdirat,将路径和权限模式传递给操作系统内核。
可以通过strace工具观察这个过程。执行strace mkdir testdir时,能看到类似mkdir("testdir", 0777) = 0的调用记录。这里的0777是默认权限,实际还会受到umask影响。用户态部分的工作很轻量,主要负责参数检查和发起系统调用,真正的目录创建动作都在内核里完成。
# 跟踪mkdir命令的系统调用
strace mkdir example_dir
# 输出中可见
# mkdir("example_dir", 0777) = 0
内核与文件系统的处理
内核收到mkdir系统调用后,会先解析路径,找到父目录的inode,并检查当前用户是否有写权限和执行权限。权限校验通过后,内核调用具体文件系统的mkdir操作函数,例如ext4的ext4_mkdir。这时文件系统会分配一个新的inode,用来记录新目录的元数据,如拥有者、时间戳、权限等。
新目录创建时,文件系统会自动为其填入两个特殊目录项:一个点号代表当前目录,指向自身inode;两个点号代表父目录,指向父inode。这就是为什么空目录也占用一定磁盘空间。不同文件系统的实现会让空目录占用大小不同,ext4下通常是4KB,而有些文件系统使用了更小块分配。
| 文件系统 | 空目录默认占用 | 特点 |
|---|---|---|
| ext4 | 4096字节 | 使用块大小为4K,元数据较完整 |
| xfs | 视配置而定 | 动态inode与Extent分配 |
| btrfs | 较小 | 采用树状结构,元数据效率高 |
权限与umask的影响
mkdir命令如果不加-m参数,会以默认模式0777去创建目录,但shell进程的umask会屏蔽掉某些权限位。例如umask为022时,最终目录权限是0755。很多新手误以为mkdir写的是777就一定是所有人可写,其实umask在中间做了减法。
如果需要明确指定权限,应该使用-m选项。下面例子中强制创建权限为700的目录,只有拥有者能进入和读写,其他用户无任何权限。这在自动化脚本中存放私密配置时非常实用。
# 创建权限严格的目录 mkdir -m 700 secret_folder # 查看结果 ls -ld secret_folder # drwx------ 2 user user 4096 空 secret_folder
常见错误与排查
执行mkdir时最常见报错是Permission denied,这说明对父目录没有写或执行权限。另一种少见但容易困惑的情况是No space left on device,有时磁盘还有剩余空间,但inode用尽了,也会建不了目录,因为mkdir必须分配新inode。
还有跨文件系统或挂载点只读的情况,mkdir同样会失败。排查时建议先用df -i看inode使用率,再用mount看挂载属性。如果是在NFS等网络文件系统上,还要考虑服务端导出权限。理清mkdir在内核与文件系统间的完整路径,定位问题就会快很多。
# 检查inode是否耗尽 df -i /path/to/parent # 检查目录所在文件系统是否只读 mount | grep /path/to/parent
小结
linux命令mkdir并不是shell凭空变出目录,而是经由用户态库函数、系统调用、内核VFS层,最终交给具体文件系统分配inode并写入目录项。它自动生成点号和点点号,受umask限制,并依赖父目录权限与磁盘inode资源。掌握这些细节,既能写对脚本,也能在出错时迅速找到根因。