findmnt JSON 输出用于脚本读取的字段选择
脚本读取 findmnt 时,最稳妥的写法不是对默认表格做 awk 切列,而是同时固定三件事:用 --json 固定格式、用 --list 固定为平铺结构、用 --output 明确字段。对“某个路径落在哪个文件系统”这类任务,通常先选 TARGET,SOURCE,FSTYPE,OPTIONS 四列就够了;需要容量计算时再显式增加 SIZE,USED,AVAIL 并配合 --bytes。
- 默认输出可能变化,脚本必须显式写出
--output列表。 - 只加
--json仍可能得到树形children;想让 jq 路径简单稳定,应同时使用--list。 - 先判断
findmnt退出状态,再解析 JSON;“没有匹配项”和“字段为空”不是同一件事。
官方手册:https://man7.org/linux/man-pages/man8/findmnt.8.html
先固定格式、结构和字段三层合同
findmnt 默认以树形表格显示挂载关系,这种输出适合人看,却不适合长期脚本接口。列宽、树形前缀和默认列都不应该成为解析依据。迁移时先写出一条最小命令:
# -J 固定 JSON,-l 关闭树形层级,-o 固定脚本依赖的字段。 findmnt -J -l -o TARGET,SOURCE,FSTYPE,OPTIONS
这四个字段各自承担明确职责:
| 字段 | 脚本用途 | 什么时候可以不选 |
|---|---|---|
TARGET | 挂载点,通常是路径匹配和结果展示的主键 | 几乎不建议省略 |
SOURCE | 设备、卷或网络文件系统来源 | 只判断文件系统类型时可省略 |
FSTYPE | ext4、xfs、tmpfs 等文件系统类型 | 完全不关心类型时可省略 |
OPTIONS | 合并后的挂载选项,用于检查 ro、rw、noexec 等状态 | 不做挂载策略判断时可省略 |
如果只需要内核 VFS 选项或文件系统专属选项,可以分别选择 VFS-OPTIONS 与 FS-OPTIONS,不要默认把 OPTIONS 拆字符串后猜测来源。当前机器到底支持哪些列,应查询已安装版本,而不是把网上的一份列清单硬编码进脚本。
# 以机器可读格式列出当前 findmnt 可用于 --output 的列。 findmnt --json --list-columns # 旧环境若不支持该组合,至少从本机帮助中核对列名。 findmnt --help

树形 JSON 与平铺 JSON 的读取路径不同
JSON 输出的根对象包含 filesystems。未启用列表模式时,挂载层级可以通过条目中的 children 继续嵌套;启用 --list 后,脚本可以把 .filesystems[] 当作平铺集合读取。这就是为什么只把旧命令后面追加 -J 还不够。
平铺命令的结果结构可以概括为:
{
"filesystems": [
{
"target": "/",
"source": "/dev/example",
"fstype": "ext4",
"options": "rw,relatime"
}
]
}
上面只是解释键名的结构示例,不代表当前机器的真实挂载结果。列名在 JSON 中以小写键出现;脚本仍应以自己传给 --output 的列集合为合同。若业务确实要保留父子挂载关系,就不要加 --list,并让 jq 递归读取可选的 children:
# 树形模式保留 children;recurse 会遍历根条目和所有子挂载。 findmnt -J -o TARGET,SOURCE,FSTYPE | jq -r '.filesystems[] | recurse(.children[]?) | [.target, .source, .fstype] | @tsv'
如果需求只是生成资产清单、判断只读挂载或查询一个路径所属的文件系统,平铺结构通常更容易维护。只有当父子挂载关系本身就是业务数据时,才值得让脚本承担递归逻辑。
查询对象要用对应的过滤参数表达
同一个字符串可能既像设备名又像挂载点。为了避免歧义,脚本中应明确使用过滤选项:
| 问题 | 推荐参数 | 结果特点 |
|---|---|---|
| 这个任意路径属于哪个文件系统 | --target /path/to/file | 会从路径向上寻找所属挂载点,最多返回一项 |
| 这个目录本身是否就是挂载点 | --mountpoint /mnt/data | 只匹配严格挂载点,不向父目录回溯 |
| 这个设备挂载到哪里 | --source /dev/... | 按挂载源过滤,可能得到多个目标 |
查询某个应用目录所属文件系统时,可以这样写:
path='/var/lib/app' # --target 接受任意文件或目录,并查找其所属文件系统。 findmnt -J -l -o TARGET,SOURCE,FSTYPE,OPTIONS --target "$path"
这里不要为了“只要一条”就用文本工具截第一行。--target 本身最多返回一个文件系统条目;若改用 --source,多个挂载目标可能都是有效结果,是否只取第一项应由业务规则决定。
新脚本先判断命令状态,再读取 filesystems
findmnt 有内容可显示时退出值为 0;无匹配、路径不存在或其他错误会返回非零状态。若把命令直接放进不检查状态的管道,脚本可能把“没有挂载信息”误判成“JSON 数组为空”。更稳妥的写法是先捕获输出,再让 jq 检查结构和字段:
#!/usr/bin/env bash
set -u
path=${1:-/var/lib/app}
# 先保存 findmnt 输出并保留它自己的退出状态。
if ! payload=$(findmnt -J -l -o TARGET,SOURCE,FSTYPE,OPTIONS --target "$path"); then
printf '未找到路径对应的文件系统,或 findmnt 执行失败: %s\n' "$path" >&2
exit 1
fi
# -e 要求表达式为真;字段缺失时脚本立即失败,而不是继续使用空字符串。
if ! jq -e '
(.filesystems | length) == 1 and
(.filesystems[0].target | type == "string") and
(.filesystems[0].source | type == "string") and
(.filesystems[0].fstype | type == "string")
' >/dev/null &2
exit 2
fi
# 最后再提取需要传给后续逻辑的字段。
jq -r '.filesystems[0] | [.target, .source, .fstype, .options] | @tsv'
OPTIONS 在某些来源或场景下可能为空,因此示例没有强制它必须是字符串。若业务要求检查 ro、rw 或 noexec,应先明确空值是失败、未知还是允许,再写对应条件。

容量字段必须同时固定单位
要做容量阈值判断时,可以增加 SIZE、USED、AVAIL 和 USE%。默认容量显示使用便于阅读的 K、M、G 等单位,脚本不应自己猜后缀。加上 --bytes 后,SIZE、USED、AVAIL 按字节输出,单位含义才适合数值比较。
# --bytes 把容量统一为字节;字段列表仍由脚本显式声明。 findmnt -J -l --bytes \ -o TARGET,SOURCE,FSTYPE,SIZE,USED,AVAIL,USE% \ --target /var/lib/app
即使使用 JSON,也不要跨发行版盲猜值一定是数字类型或字符串类型。最稳妥的方法是在 jq 中按目标环境的实际类型做断言,或者使用 tonumber 明确转换;升级 util-linux 后,把类型检查纳入回归用例。
从旧脚本迁移时逐项回归
迁移不是把 findmnt 后面简单加一个 -J。建议按下面清单逐项核对:
- 命令包含
--json、--list和完整的--output列表。 - 脚本从
.filesystems[]读取,不依赖表格列宽、空格数量或树形字符。 - 按查询意图选择
--target、--mountpoint或--source。 - 在调用 jq 之前保存并判断
findmnt的退出状态。 - 容量计算显式使用
--bytes,升级后复查 JSON 值类型。 - 多挂载结果不随意取第一条,是否允许多项由业务合同决定。
- 测试至少覆盖正常挂载点、普通子目录、不存在路径和一个可能多结果的源设备。
相关问题
findmnt -J 为什么还有 children?
-J 只选择 JSON 格式,默认挂载视图仍可以保持树形关系。脚本想读取平铺数组时,再加 --list。
脚本只查挂载点时需要哪些字段?
多数场景从 TARGET,SOURCE,FSTYPE,OPTIONS 开始即可。只有确实要做容量、UUID、传播属性或 VFS/文件系统选项区分时,再增加对应列。
为什么不建议解析 mount 命令的文本输出?
findmnt 提供可定制字段和 JSON 格式,更适合作为脚本接口;显式字段合同也更容易在系统升级时做回归检查。
米坛社区是不是小米官方?社区定位、品牌归属与入口辨别
- 上一篇
- 米坛社区是不是小米官方?社区定位、品牌归属与入口辨别
- 下一篇
- shizuku重启后授权还在吗?服务状态与应用授权区别说明
-
- 文章 · linux | 20小时前 |
- Linux ip rule 怎么按来源地址选择路由表
- 347浏览 收藏
-
- 文章 · linux | 23小时前 | Linux · 文件系统 · Linux mount bind mount remount
- Linux bind mount 怎么二次挂载为只读
- 116浏览 收藏
-
- 文章 · linux | 1天前 |
- systemd-sysusers 怎么声明软件包所需系统账号
- 150浏览 收藏
-
- 文章 · linux | 1天前 |
- systemd-tmpfiles 怎么按文件年龄自动清理目录
- 464浏览 收藏
-
- 文章 · linux | 1天前 |
- cgroup v2 memory.high 与 memory.max 有什么区别
- 481浏览 收藏
-
- 文章 · linux | 1天前 | Linux · Linux systemd journalctl
- journalctl 多个字段条件怎么组合 AND 与 OR
- 228浏览 收藏
-
- 文章 · linux | 2天前 |
- systemd journal namespace 怎么隔离服务日志
- 442浏览 收藏
-
- 文章 · linux | 2天前 | 缓存 · Linux ·
- Linux tmpfs缓存目录的容量与重启清空边界
- 279浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 256次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 298次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 275次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 253次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 61次使用
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- 使用golang获取linux上文件的访问/创建/修改时间
- 2022-12-31 238浏览
-
- 在Linux系统中安装Go语言的详细教程
- 2022-12-29 402浏览
