Linux 命令:mknod

Linux 命令:mknod

mknod 是 Linux 中手动创建特殊设备文件 的专用命令,核心作用是在 /dev 等目录下创建字符设备(char)、块设备(block)和命名管道(FIFO)文件,为内核设备驱动、进程间通信提供文件系统级的访问接口。Linux 中所有设备均以文件形式存在,大部分设备文件由系统自动创建,而 mknod 用于手动创建自定义/特殊设备文件,是内核开发、设备驱动调试、系统运维的基础工具。

资料合集:https://pan.quark.cn/s/6fe3007c3e95https://pan.quark.cn/s/561de99256a5https://pan.quark.cn/s/985f55b13d94https://pan.quark.cn/s/d0fb20abd19a

核心背景

Linux 遵循一切皆文件 的设计理念,硬件设备(如硬盘、串口、显卡)、内核虚拟设备均通过设备文件 在文件系统中暴露接口,用户空间程序通过读写设备文件与内核设备驱动交互,无需直接操作硬件。

设备文件分为两类核心类型,且均有唯一的主设备号(major)次设备号(minor)

  1. 字符设备:按字节流顺序访问,无缓存,如串口(tty)、键盘、鼠标、/dev/null,主设备号标识设备驱动,次设备号标识同驱动下的不同设备;
  2. 块设备:按固定大小块访问,有缓存,如硬盘(sd*)、U盘、分区,主/次设备号作用与字符设备一致;
  3. 命名管道(FIFO):特殊的进程间通信(IPC)文件,无主/次设备号,用于同一主机上的进程间数据传输。

系统默认通过 udev 机制自动创建设备文件,但在内核调试、自定义设备开发、系统初始化异常等场景下,需通过 mknod 手动创建设备文件,这是该命令的核心使用场景。

核心特点

  1. 专创特殊文件:仅用于创建字符设备、块设备、命名管道,无法创建普通文件/目录;
  2. 需指定设备标识:创建设备文件时必须指定主/次设备号,创建命名管道无需指定;
  3. 依赖内核驱动:创建的设备文件仅当内核存在对应主设备号的驱动时,才能实现实际设备访问;
  4. 权限可控:创建的文件支持通过 chmod/chown 修改传统权限,结合 ACL 实现精细化访问控制;
  5. 仅root可执行:创建设备文件需要root 权限(CAP_MKNOD 能力),普通用户无执行权限,保证系统设备安全;
  6. 轻量无依赖:直接与内核交互,无额外依赖,执行后立即在文件系统中生成对应特殊文件。

基本语法

mknod 语法围绕文件类型、设备号 设计,核心分为创建设备文件创建命名管道 两类,创建设备文件时必须指定主/次设备号,格式为主设备号.次设备号主设备号 次设备号

bash 复制代码
# 核心语法:创建字符/块设备文件(需root权限)
mknod [选项] 设备文件名 [b|c|u] 主设备号 次设备号

# 语法:创建命名管道(FIFO)文件
mknod [选项] 管道文件名 p

# 简写格式:主/次设备号可用点分隔(与空格等价)
mknod 设备文件名 c 1 3  ===  mknod 设备文件名 c 1.3

关键类型标识说明

标识 文件类型 核心特性 示例
b 块设备文件 块访问、有缓存,需主/次设备号 硬盘:mknod /dev/sdb b 8 16
c 字符设备文件 字节流访问、无缓存,需主/次设备号 空设备:mknod /dev/null c 1 3
u 字符设备文件(无缓冲) 与c一致,部分系统为兼容标识,优先用c 同c类型,无实际差异
p 命名管道(FIFO) 进程间通信,无主/次设备号,无设备驱动关联 管道:mknod /tmp/fifo.p p

主/次设备号说明

  1. 主设备号(0-4095):标识内核中的设备驱动程序,相同主设备号对应同一驱动;
  2. 次设备号(0-255/65535):标识同一驱动下的不同物理/虚拟设备,如硬盘分区、多个串口;
  3. 号段分配:内核有固定的设备号分配规则(可通过cat /proc/devices查看已注册的主设备号),自定义设备建议使用未分配的号段。

常用选项

mknod 设计极简,仅提供少量基础选项,围绕文件权限、创建路径设计,无冗余功能,日常使用掌握3个核心选项即可覆盖所有场景:

选项 核心作用 实用场景
-m 指定创建文件的初始权限 无需创建后再执行chmod,直接设置权限,如-m 666表示所有用户读写
-Z 设置文件的SELinux安全上下文 开启SELinux的系统中,直接指定上下文,避免后续执行chcon
--help 显示帮助信息 快速查看语法、类型标识说明,无需查阅手册

权限说明

  1. 设备文件权限:传统rwx权限,r为读设备、w为写设备、x一般无意义(部分设备用于执行/ioctl);
  2. 命名管道权限:r为读管道、w为写管道,无x权限;
  3. 默认权限:未指定-m时,默认权限为0600(仅root读写),需根据需求修改。

经典实操示例

mknod 的使用场景分为创建设备文件创建命名管道 两大类,所有操作均需root权限(sudo/切换root),示例贴合内核调试、系统运维、进程间通信的真实场景,可直接复用。

前置准备

  1. 切换为root用户或使用sudo,获取执行权限;
  2. 查看系统已注册的设备号:cat /proc/devices(查看字符设备用cat /proc/char_devices,块设备用cat /proc/block_devices);
  3. 验证特殊文件类型:用ls -l查看,设备文件首字符为b/c,命名管道首字符为p
bash 复制代码
# 切换root
su - root
# 查看已注册的字符/块设备主设备号
cat /proc/devices
# 示例输出:字符设备1为mem,3为tty,11为sound;块设备8为sd(硬盘)

场景1:创建经典字符设备------/dev/null(空设备)

/dev/null 是Linux核心的字符设备,用于丢弃所有写入的数据,读取则返回空,手动创建可验证mknod基础用法,主设备号1、次设备号3为内核固定分配:

bash 复制代码
# 创建字符设备/dev/mynull,主1次3,初始权限666(所有用户读写)
mknod -m 666 /dev/mynull c 1 3

# 验证文件类型和权限(ls -l首字符为c,权限-rw-rw-rw-)
ls -l /dev/mynull
# 输出示例:crw-rw-rw- 1 root root 1, 3  月  日 时:分 /dev/mynull

# 测试设备功能(写入数据无输出,读取无内容)
echo "test" > /dev/mynull
cat /dev/mynull

场景2:创建块设备文件------硬盘分区设备

为硬盘分区创建手动设备文件,需先确认分区的主/次设备号(硬盘主设备号固定为8,次设备号按分区规则分配:sda1为1,sda2为2,sdb1为17,依此类推):

bash 复制代码
# 创建块设备/dev/my_sdb1,对应U盘分区sdb1,主8次17,权限644
mknod -m 644 /dev/my_sdb1 b 8 17

# 验证文件类型(首字符为b)
ls -l /dev/my_sdb1
# 输出示例:brw-r--r-- 1 root root 8, 17  月  日 时:分 /dev/my_sdb1

# 测试访问(查看分区文件系统)
blkid /dev/my_sdb1

场景3:创建命名管道(FIFO)------进程间通信

创建命名管道实现两个进程间的单向数据传输,无需主/次设备号,标识为p,管道遵循先进先出原则,读进程会阻塞至有写进程写入数据:

bash 复制代码
# 创建命名管道/tmp/ipc_fifo,初始权限666
mknod -m 666 /tmp/ipc_fifo p

# 验证文件类型(首字符为p)
ls -l /tmp/ipc_fifo
# 输出示例:prw-rw-rw- 1 root root 0  月  日 时:分 /tmp/ipc_fifo

# 测试进程间通信(打开两个终端)
# 终端1:读管道(阻塞,直到终端2写入数据)
cat /tmp/ipc_fifo
# 终端2:写管道(写入后终端1立即输出内容)
echo "Hello Linux IPC" > /tmp/ipc_fifo

场景4:创建自定义字符设备------内核调试

内核开发中,为自定义字符设备驱动创建设备文件,假设自定义驱动注册的主设备号为240(未分配号段),次设备号0为第一个自定义设备:

bash 复制代码
# 创建自定义字符设备/dev/mydev,主240次0,权限600(仅root访问)
mknod -m 600 /dev/mydev c 240 0

# 验证设备文件
ls -l /dev/mydev
# 输出示例:crw------- 1 root root 240, 0  月  日 时:分 /dev/mydev

# 加载自定义驱动后,即可通过该文件与驱动交互
insmod mydev.ko
cat /dev/mydev  # 读设备数据
echo "cmd" > /dev/mydev  # 写设备指令

场景5:删除已创建的特殊文件

mknod 仅负责创建特殊文件,删除直接使用rm命令,与删除普通文件一致,删除后文件系统接口消失,不影响内核驱动:

bash 复制代码
# 删除手动创建的字符设备
rm -f /dev/mynull
# 删除命名管道
rm -f /tmp/ipc_fifo
# 删除自定义块设备
rm -f /dev/my_sdb1

高频组合用法

mknod 常与ls -l(验证文件类型)、cat /proc/devices(查看设备号)、chmod/chown(修改权限)、insmod/rmmod(内核驱动操作)搭配,形成设备文件创建-驱动加载-权限配置-设备访问的完整流程,是内核开发、设备调试的标准操作组合。

组合1:自定义字符设备「驱动加载-设备创建-访问测试」

bash 复制代码
# 步骤1:查看未分配的主设备号(确认240未被使用)
cat /proc/devices
# 步骤2:加载自定义内核驱动
insmod mychar_dev.ko
# 步骤3:创建设备文件,主240次0,权限660(root和dev组可访问)
mknod -m 660 /dev/mychar c 240 0
chown root:dev /dev/mychar
# 步骤4:测试设备访问(读驱动返回的测试数据)
cat /dev/mychar
# 步骤5:卸载驱动并删除设备文件
rmmod mychar_dev
rm -f /dev/mychar

组合2:命名管道「创建-多进程通信-清理」

bash 复制代码
# 步骤1:创建命名管道,权限600(仅当前用户)
sudo mknod -m 600 /tmp/fifo p
sudo chown $USER:$USER /tmp/fifo
# 步骤2:终端1:启动读进程(持续读取管道数据)
while true; do cat /tmp/fifo; done
# 步骤3:终端2:启动写进程(向管道写入日志)
tail -f /var/log/messages > /tmp/fifo
# 步骤4:结束通信,清理管道
rm -f /tmp/fifo

组合3:系统设备恢复------手动重建/dev/tty(串口设备)

系统udev异常导致/dev/tty1(虚拟控制台)丢失时,手动重建,主设备号4、次设备号1为内核固定分配:

bash 复制代码
# 步骤1:查看串口设备主设备号
grep tty /proc/devices
# 步骤2:重建tty1,主4次1,权限620(root和tty组)
mknod -m 620 /dev/tty1 c 4 1
chown root:tty /dev/tty1
# 步骤3:验证设备可用
ls /dev/tty1

关键注意事项

  1. 必须root权限:执行mknod需要root或CAP_MKNOD能力,普通用户执行会提示「权限拒绝」,可通过sudo提升权限;
  2. 设备号需匹配内核:创建的设备文件主设备号必须与内核中已注册的驱动一致,否则读写文件会提示「没有那个设备或地址」;
  3. 勿修改系统默认设备:系统自动创建的/dev下设备文件(如sd*、tty*、null)请勿手动删除/重建,否则会导致设备无法使用,异常时通过udevadm trigger重建;
  4. 命名管道与匿名管道的区别:mknod创建的是命名管道(FIFO) ,有文件系统路径,可跨任意进程使用;匿名管道由|创建,无路径,仅能用于父子进程间通信;
  5. 设备文件无实际数据:设备文件仅为访问接口,无实际文件内容,文件大小始终为0,读写操作均映射为内核驱动的函数调用;
  6. 权限配置需谨慎:设备文件权限过宽(如666)会导致普通用户随意访问/操作设备,造成系统安全风险,建议按「最小权限原则」配置(如仅root访问为600);
  7. 自定义设备号避用已分配段:查看/proc/devices确认未分配的主设备号,自定义设备建议使用240-255(内核预留的自定义号段),避免与系统设备冲突。

与mkfifo的区别

mkfifo 是专门创建命名管道 的命令,与mknod 文件名 p功能完全一致,二者是等价实现,核心区别仅为专用性,可根据使用习惯选择:

命令 支持创建的文件类型 核心用途 等价用法
mknod 字符设备、块设备、命名管道 通用特殊文件创建,侧重设备文件 mknod fifo.p p = mkfifo fifo.p
mkfifo 仅命名管道 专用命名管道创建,侧重进程间通信 无其他功能,仅等价于mknod的p类型

使用建议:创建设备文件用mknod,创建命名管道用mkfifo,更符合命令语义,便于代码/脚本的可读性。

总结

mknod 是 Linux 中手动创建特殊设备文件的核心工具,核心价值是为内核设备驱动、进程间通信提供文件系统级的访问接口,实现用户空间与内核空间的交互,是内核开发、设备驱动调试、系统异常恢复的基础工具,核心要点可总结为:

  1. 核心功能:创建字符设备(c)、块设备(b)、命名管道(p),其中设备文件需指定主/次设备号,命名管道无需;
  2. 核心前提:必须root权限,设备文件主设备号需与内核驱动匹配,否则无法实际使用;
  3. 常用选项:-m指定初始权限,是最核心的实用选项,避免后续执行chmod;
  4. 类型识别:通过ls -l首字符区分类型(b=块、c=字符、p=管道),所有特殊文件大小均为0;
  5. 配套工具:与cat /proc/devices(查设备号)、insmod(加载驱动)、chmod/chown(配权限)搭配使用;
  6. 避坑关键:勿修改系统默认设备文件,按最小权限原则配置设备权限,自定义设备号使用内核预留段。
相关推荐
安科士andxe6 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
小白同学_C9 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖9 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
2601_9491465310 小时前
Shell语音通知接口使用指南:运维自动化中的语音告警集成方案
运维·自动化
儒雅的晴天10 小时前
大模型幻觉问题
运维·服务器
Gofarlic_OMS11 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
通信大师11 小时前
深度解析PCC策略计费控制:核心网产品与应用价值
运维·服务器·网络·5g
dixiuapp11 小时前
智能工单系统如何选,实现自动化与预测性维护
运维·自动化
不做无法实现的梦~11 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
Elastic 中国社区官方博客11 小时前
如何防御你的 RAG 系统免受上下文投毒攻击
大数据·运维·人工智能·elasticsearch·搜索引擎·ai·全文检索