myspace-cli 1.3.0__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/PKG-INFO +54 -27
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/README.md +53 -26
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/PKG-INFO +54 -27
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/pyproject.toml +1 -1
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/space_cli.py +171 -34
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/SOURCES.txt +0 -0
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/dependency_links.txt +0 -0
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/entry_points.txt +0 -0
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/requires.txt +0 -0
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/myspace_cli.egg-info/top_level.txt +0 -0
- {myspace_cli-1.3.0 → myspace_cli-1.4.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: myspace-cli
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.0
|
4
4
|
Summary: A macOS disk space analysis CLI: health, index, app usage, big files.
|
5
5
|
Author-email: Your Name <you@example.com>
|
6
6
|
License: MIT
|
@@ -17,28 +17,29 @@ Description-Content-Type: text/markdown
|
|
17
17
|
Provides-Extra: mcp
|
18
18
|
Requires-Dist: mcp<2,>=1; extra == "mcp"
|
19
19
|
|
20
|
-
# space-cli -
|
20
|
+
# space-cli - macOS 磁盘空间优化工具
|
21
21
|
|
22
22
|
很多人的Mac电脑都会出现磁盘空间不够用,付费软件太贵或者难以使用。
|
23
23
|
|
24
|
-
space-cli是一个开源的
|
24
|
+
space-cli是一个开源的macOS命令行小工具,用于分析磁盘空间健康度并找出占用空间大的目录,可选择针对单个应用进行一键清理。
|
25
25
|
|
26
26
|
本软件采用**最严安全原则**,所有分析操作采用只读模式,未经允许不会尝试改写和破坏用户电脑的任何数据,也不会上传任何数据到外网,严格保护用户的隐私。
|
27
27
|
|
28
28
|
## 功能特性
|
29
29
|
|
30
30
|
- 🔍 **磁盘健康度检测** - 评估磁盘空间使用情况,提供健康状态建议
|
31
|
-
- 📊
|
32
|
-
- 💻
|
31
|
+
- 📊 **交互式目录分析** - 递归分析目录大小,支持选择序号进行深度下探分析
|
32
|
+
- 💻 **详细系统信息** - 显示CPU、内存、GPU、硬盘等完整硬件信息
|
33
33
|
- 📄 **报告导出** - 将分析结果导出为JSON格式报告
|
34
|
-
- ⚡
|
34
|
+
- ⚡ **高性能优化** - 优先使用 `du -sk` 命令,失败时回退到 `os.scandir` 高效遍历
|
35
35
|
- 🎯 **灵活配置** - 支持自定义分析路径和显示数量
|
36
|
-
- 🗂️
|
36
|
+
- 🗂️ **智能索引缓存** - 目录大小结果本地索引缓存(`~/.spacecli/index.json`),支持TTL与重建提示
|
37
37
|
- 🧩 **应用分析** - 汇总 `Applications`、`Library`、`Caches`、`Logs` 等路径估算应用占用,给出卸载建议
|
38
38
|
- 🗑️ **一键删除应用** - 在应用分析列表中输入序号即可一键删除所选应用及其缓存(含二次确认)
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
- 🏠 **用户目录深度分析** - 针对 `~/Library`、`~/Downloads`、`~/Documents` 分别下探并展示Top N目录
|
40
|
+
- 🗄️ **大文件分析** - 扫描并列出指定路径下最大的文件,支持数量和最小体积阈值
|
41
|
+
- 🔄 **返回上一级** - 在下探分析中支持选择0返回上一级目录
|
42
|
+
- ⏱️ **支持MCP调用** - 支持你自己的AI Agent无缝调用磁盘空间信息
|
42
43
|
|
43
44
|
## 安装
|
44
45
|
|
@@ -51,10 +52,16 @@ python3 -m pip install --upgrade myspace-cli
|
|
51
52
|
pip install myspace-cli
|
52
53
|
|
53
54
|
# 安装完成后直接使用
|
54
|
-
space-cli
|
55
|
+
# 请注意命令行的启动文件名(space-cli)和pip包的名字(myspace-cli)不一样
|
56
|
+
# 建议直接运行,可以看到使用菜单
|
57
|
+
space-cli
|
55
58
|
|
56
59
|
# 或以模块方式
|
57
|
-
python3 -m space_cli
|
60
|
+
python3 -m space_cli
|
61
|
+
|
62
|
+
# 如果要使用高级的功能,请使用更复杂的命令行参数,可以运行help
|
63
|
+
space-cli --help
|
64
|
+
|
58
65
|
```
|
59
66
|
|
60
67
|
### 方法2:直接使用
|
@@ -89,7 +96,7 @@ space-cli
|
|
89
96
|
### 基本用法
|
90
97
|
|
91
98
|
```bash
|
92
|
-
#
|
99
|
+
# 分析根目录(默认)- 支持交互式下探分析
|
93
100
|
python3 space_cli.py
|
94
101
|
|
95
102
|
# 分析指定路径
|
@@ -100,6 +107,9 @@ python3 space_cli.py -n 10
|
|
100
107
|
|
101
108
|
# 快捷分析当前用户目录(含用户目录深度分析)
|
102
109
|
python3 space_cli.py --home
|
110
|
+
|
111
|
+
# 交互式目录空间分析(支持选择序号下探,选择0返回上一级)
|
112
|
+
python3 space_cli.py --directories-only
|
103
113
|
```
|
104
114
|
|
105
115
|
### 高级用法
|
@@ -182,21 +192,30 @@ python3 space_cli.py --big-files --export report.json
|
|
182
192
|
建议: 磁盘空间不足,建议清理一些文件
|
183
193
|
```
|
184
194
|
|
185
|
-
###
|
195
|
+
### 交互式目录分析
|
186
196
|
```
|
187
197
|
============================================================
|
188
198
|
📊 占用空间最大的目录
|
189
199
|
============================================================
|
190
200
|
显示前 20 个最大的目录:
|
191
201
|
|
192
|
-
1. /Applications
|
193
|
-
大小:
|
202
|
+
1. /Applications -- 大小: 15.2 GB (3.04%)
|
203
|
+
2. /Users/username/Library -- 大小: 8.5 GB (1.70%)
|
204
|
+
3. /System -- 大小: 6.8 GB (1.36%)
|
194
205
|
|
195
|
-
|
196
|
-
|
206
|
+
============================================================
|
207
|
+
🔍 下探分析选项
|
208
|
+
============================================================
|
209
|
+
选择序号进行深度分析,选择0返回上一级,直接回车退出:
|
210
|
+
请输入选择 [回车=退出]: 1
|
197
211
|
|
198
|
-
|
199
|
-
|
212
|
+
🔍 正在分析: /Applications (15.2 GB)
|
213
|
+
============================================================
|
214
|
+
📊 占用空间最大的目录
|
215
|
+
============================================================
|
216
|
+
1. /Applications/Xcode.app -- 大小: 8.2 GB (1.64%)
|
217
|
+
2. /Applications/Docker.app -- 大小: 3.1 GB (0.62%)
|
218
|
+
3. /Applications/Visual Studio Code.app -- 大小: 1.8 GB (0.36%)
|
200
219
|
```
|
201
220
|
|
202
221
|
### 大文件分析
|
@@ -257,12 +276,13 @@ python3 mcp_server.py
|
|
257
276
|
|
258
277
|
## 性能优化
|
259
278
|
|
260
|
-
-
|
261
|
-
-
|
262
|
-
-
|
263
|
-
-
|
264
|
-
|
265
|
-
|
279
|
+
- **优先使用 `du -sk` 命令**:在 macOS 上使用原生 `du` 命令快速获取目录大小
|
280
|
+
- **智能回退机制**:当 `du` 命令失败时,自动回退到基于 `os.scandir` 的高效遍历
|
281
|
+
- **跳过系统目录**:自动忽略 `/System`、`/Volumes`、`/private` 等系统目录
|
282
|
+
- **跳过无法访问的文件**:自动处理权限错误和符号链接
|
283
|
+
- **支持中断操作**:使用 Ctrl+C 随时中断分析
|
284
|
+
- **内存优化遍历**:使用栈式迭代替代递归,避免深度目录的栈溢出
|
285
|
+
- **单行滚动进度**:避免输出刷屏,使用 ANSI 清行(\r\033[K)避免长行残留
|
266
286
|
|
267
287
|
## 故障排除
|
268
288
|
|
@@ -321,7 +341,14 @@ MIT License
|
|
321
341
|
- 单行滚动进度显示
|
322
342
|
|
323
343
|
### v1.2.0
|
324
|
-
-
|
344
|
+
- 应用分析支持"按序号一键删除应用",并显示将删除的路径清单与预计释放空间
|
325
345
|
- 删除过程增加权限修复与降级清理策略(chflags nouchg / chmod 0777 / 逐项清理)
|
326
346
|
- 针对 "Operation not permitted" 增加友好提示(SIP、完全磁盘访问、退出相关应用)
|
327
347
|
- 单行覆盖输出加入 ANSI 清行,避免长行残留
|
348
|
+
|
349
|
+
### v1.3.0
|
350
|
+
- **性能大幅优化**:优先使用 `du -sk` 命令获取目录大小,失败时回退到 `os.scandir` 高效遍历
|
351
|
+
- **交互式下探分析**:支持选择序号进行深度目录分析,选择0返回上一级
|
352
|
+
- **增强系统信息**:显示 CPU、内存、GPU、硬盘等完整硬件信息
|
353
|
+
- **智能目录过滤**:自动忽略系统目录(`/System`、`/Volumes`、`/private`)
|
354
|
+
- **优化用户体验**:改进菜单选项,支持交互式目录空间分析
|
@@ -1,25 +1,26 @@
|
|
1
|
-
# space-cli -
|
1
|
+
# space-cli - macOS 磁盘空间优化工具
|
2
2
|
|
3
3
|
很多人的Mac电脑都会出现磁盘空间不够用,付费软件太贵或者难以使用。
|
4
4
|
|
5
|
-
space-cli是一个开源的
|
5
|
+
space-cli是一个开源的macOS命令行小工具,用于分析磁盘空间健康度并找出占用空间大的目录,可选择针对单个应用进行一键清理。
|
6
6
|
|
7
7
|
本软件采用**最严安全原则**,所有分析操作采用只读模式,未经允许不会尝试改写和破坏用户电脑的任何数据,也不会上传任何数据到外网,严格保护用户的隐私。
|
8
8
|
|
9
9
|
## 功能特性
|
10
10
|
|
11
11
|
- 🔍 **磁盘健康度检测** - 评估磁盘空间使用情况,提供健康状态建议
|
12
|
-
- 📊
|
13
|
-
- 💻
|
12
|
+
- 📊 **交互式目录分析** - 递归分析目录大小,支持选择序号进行深度下探分析
|
13
|
+
- 💻 **详细系统信息** - 显示CPU、内存、GPU、硬盘等完整硬件信息
|
14
14
|
- 📄 **报告导出** - 将分析结果导出为JSON格式报告
|
15
|
-
- ⚡
|
15
|
+
- ⚡ **高性能优化** - 优先使用 `du -sk` 命令,失败时回退到 `os.scandir` 高效遍历
|
16
16
|
- 🎯 **灵活配置** - 支持自定义分析路径和显示数量
|
17
|
-
- 🗂️
|
17
|
+
- 🗂️ **智能索引缓存** - 目录大小结果本地索引缓存(`~/.spacecli/index.json`),支持TTL与重建提示
|
18
18
|
- 🧩 **应用分析** - 汇总 `Applications`、`Library`、`Caches`、`Logs` 等路径估算应用占用,给出卸载建议
|
19
19
|
- 🗑️ **一键删除应用** - 在应用分析列表中输入序号即可一键删除所选应用及其缓存(含二次确认)
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
- 🏠 **用户目录深度分析** - 针对 `~/Library`、`~/Downloads`、`~/Documents` 分别下探并展示Top N目录
|
21
|
+
- 🗄️ **大文件分析** - 扫描并列出指定路径下最大的文件,支持数量和最小体积阈值
|
22
|
+
- 🔄 **返回上一级** - 在下探分析中支持选择0返回上一级目录
|
23
|
+
- ⏱️ **支持MCP调用** - 支持你自己的AI Agent无缝调用磁盘空间信息
|
23
24
|
|
24
25
|
## 安装
|
25
26
|
|
@@ -32,10 +33,16 @@ python3 -m pip install --upgrade myspace-cli
|
|
32
33
|
pip install myspace-cli
|
33
34
|
|
34
35
|
# 安装完成后直接使用
|
35
|
-
space-cli
|
36
|
+
# 请注意命令行的启动文件名(space-cli)和pip包的名字(myspace-cli)不一样
|
37
|
+
# 建议直接运行,可以看到使用菜单
|
38
|
+
space-cli
|
36
39
|
|
37
40
|
# 或以模块方式
|
38
|
-
python3 -m space_cli
|
41
|
+
python3 -m space_cli
|
42
|
+
|
43
|
+
# 如果要使用高级的功能,请使用更复杂的命令行参数,可以运行help
|
44
|
+
space-cli --help
|
45
|
+
|
39
46
|
```
|
40
47
|
|
41
48
|
### 方法2:直接使用
|
@@ -70,7 +77,7 @@ space-cli
|
|
70
77
|
### 基本用法
|
71
78
|
|
72
79
|
```bash
|
73
|
-
#
|
80
|
+
# 分析根目录(默认)- 支持交互式下探分析
|
74
81
|
python3 space_cli.py
|
75
82
|
|
76
83
|
# 分析指定路径
|
@@ -81,6 +88,9 @@ python3 space_cli.py -n 10
|
|
81
88
|
|
82
89
|
# 快捷分析当前用户目录(含用户目录深度分析)
|
83
90
|
python3 space_cli.py --home
|
91
|
+
|
92
|
+
# 交互式目录空间分析(支持选择序号下探,选择0返回上一级)
|
93
|
+
python3 space_cli.py --directories-only
|
84
94
|
```
|
85
95
|
|
86
96
|
### 高级用法
|
@@ -163,21 +173,30 @@ python3 space_cli.py --big-files --export report.json
|
|
163
173
|
建议: 磁盘空间不足,建议清理一些文件
|
164
174
|
```
|
165
175
|
|
166
|
-
###
|
176
|
+
### 交互式目录分析
|
167
177
|
```
|
168
178
|
============================================================
|
169
179
|
📊 占用空间最大的目录
|
170
180
|
============================================================
|
171
181
|
显示前 20 个最大的目录:
|
172
182
|
|
173
|
-
1. /Applications
|
174
|
-
大小:
|
183
|
+
1. /Applications -- 大小: 15.2 GB (3.04%)
|
184
|
+
2. /Users/username/Library -- 大小: 8.5 GB (1.70%)
|
185
|
+
3. /System -- 大小: 6.8 GB (1.36%)
|
175
186
|
|
176
|
-
|
177
|
-
|
187
|
+
============================================================
|
188
|
+
🔍 下探分析选项
|
189
|
+
============================================================
|
190
|
+
选择序号进行深度分析,选择0返回上一级,直接回车退出:
|
191
|
+
请输入选择 [回车=退出]: 1
|
178
192
|
|
179
|
-
|
180
|
-
|
193
|
+
🔍 正在分析: /Applications (15.2 GB)
|
194
|
+
============================================================
|
195
|
+
📊 占用空间最大的目录
|
196
|
+
============================================================
|
197
|
+
1. /Applications/Xcode.app -- 大小: 8.2 GB (1.64%)
|
198
|
+
2. /Applications/Docker.app -- 大小: 3.1 GB (0.62%)
|
199
|
+
3. /Applications/Visual Studio Code.app -- 大小: 1.8 GB (0.36%)
|
181
200
|
```
|
182
201
|
|
183
202
|
### 大文件分析
|
@@ -238,12 +257,13 @@ python3 mcp_server.py
|
|
238
257
|
|
239
258
|
## 性能优化
|
240
259
|
|
241
|
-
-
|
242
|
-
-
|
243
|
-
-
|
244
|
-
-
|
245
|
-
|
246
|
-
|
260
|
+
- **优先使用 `du -sk` 命令**:在 macOS 上使用原生 `du` 命令快速获取目录大小
|
261
|
+
- **智能回退机制**:当 `du` 命令失败时,自动回退到基于 `os.scandir` 的高效遍历
|
262
|
+
- **跳过系统目录**:自动忽略 `/System`、`/Volumes`、`/private` 等系统目录
|
263
|
+
- **跳过无法访问的文件**:自动处理权限错误和符号链接
|
264
|
+
- **支持中断操作**:使用 Ctrl+C 随时中断分析
|
265
|
+
- **内存优化遍历**:使用栈式迭代替代递归,避免深度目录的栈溢出
|
266
|
+
- **单行滚动进度**:避免输出刷屏,使用 ANSI 清行(\r\033[K)避免长行残留
|
247
267
|
|
248
268
|
## 故障排除
|
249
269
|
|
@@ -302,7 +322,14 @@ MIT License
|
|
302
322
|
- 单行滚动进度显示
|
303
323
|
|
304
324
|
### v1.2.0
|
305
|
-
-
|
325
|
+
- 应用分析支持"按序号一键删除应用",并显示将删除的路径清单与预计释放空间
|
306
326
|
- 删除过程增加权限修复与降级清理策略(chflags nouchg / chmod 0777 / 逐项清理)
|
307
327
|
- 针对 "Operation not permitted" 增加友好提示(SIP、完全磁盘访问、退出相关应用)
|
308
328
|
- 单行覆盖输出加入 ANSI 清行,避免长行残留
|
329
|
+
|
330
|
+
### v1.3.0
|
331
|
+
- **性能大幅优化**:优先使用 `du -sk` 命令获取目录大小,失败时回退到 `os.scandir` 高效遍历
|
332
|
+
- **交互式下探分析**:支持选择序号进行深度目录分析,选择0返回上一级
|
333
|
+
- **增强系统信息**:显示 CPU、内存、GPU、硬盘等完整硬件信息
|
334
|
+
- **智能目录过滤**:自动忽略系统目录(`/System`、`/Volumes`、`/private`)
|
335
|
+
- **优化用户体验**:改进菜单选项,支持交互式目录空间分析
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: myspace-cli
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.0
|
4
4
|
Summary: A macOS disk space analysis CLI: health, index, app usage, big files.
|
5
5
|
Author-email: Your Name <you@example.com>
|
6
6
|
License: MIT
|
@@ -17,28 +17,29 @@ Description-Content-Type: text/markdown
|
|
17
17
|
Provides-Extra: mcp
|
18
18
|
Requires-Dist: mcp<2,>=1; extra == "mcp"
|
19
19
|
|
20
|
-
# space-cli -
|
20
|
+
# space-cli - macOS 磁盘空间优化工具
|
21
21
|
|
22
22
|
很多人的Mac电脑都会出现磁盘空间不够用,付费软件太贵或者难以使用。
|
23
23
|
|
24
|
-
space-cli是一个开源的
|
24
|
+
space-cli是一个开源的macOS命令行小工具,用于分析磁盘空间健康度并找出占用空间大的目录,可选择针对单个应用进行一键清理。
|
25
25
|
|
26
26
|
本软件采用**最严安全原则**,所有分析操作采用只读模式,未经允许不会尝试改写和破坏用户电脑的任何数据,也不会上传任何数据到外网,严格保护用户的隐私。
|
27
27
|
|
28
28
|
## 功能特性
|
29
29
|
|
30
30
|
- 🔍 **磁盘健康度检测** - 评估磁盘空间使用情况,提供健康状态建议
|
31
|
-
- 📊
|
32
|
-
- 💻
|
31
|
+
- 📊 **交互式目录分析** - 递归分析目录大小,支持选择序号进行深度下探分析
|
32
|
+
- 💻 **详细系统信息** - 显示CPU、内存、GPU、硬盘等完整硬件信息
|
33
33
|
- 📄 **报告导出** - 将分析结果导出为JSON格式报告
|
34
|
-
- ⚡
|
34
|
+
- ⚡ **高性能优化** - 优先使用 `du -sk` 命令,失败时回退到 `os.scandir` 高效遍历
|
35
35
|
- 🎯 **灵活配置** - 支持自定义分析路径和显示数量
|
36
|
-
- 🗂️
|
36
|
+
- 🗂️ **智能索引缓存** - 目录大小结果本地索引缓存(`~/.spacecli/index.json`),支持TTL与重建提示
|
37
37
|
- 🧩 **应用分析** - 汇总 `Applications`、`Library`、`Caches`、`Logs` 等路径估算应用占用,给出卸载建议
|
38
38
|
- 🗑️ **一键删除应用** - 在应用分析列表中输入序号即可一键删除所选应用及其缓存(含二次确认)
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
- 🏠 **用户目录深度分析** - 针对 `~/Library`、`~/Downloads`、`~/Documents` 分别下探并展示Top N目录
|
40
|
+
- 🗄️ **大文件分析** - 扫描并列出指定路径下最大的文件,支持数量和最小体积阈值
|
41
|
+
- 🔄 **返回上一级** - 在下探分析中支持选择0返回上一级目录
|
42
|
+
- ⏱️ **支持MCP调用** - 支持你自己的AI Agent无缝调用磁盘空间信息
|
42
43
|
|
43
44
|
## 安装
|
44
45
|
|
@@ -51,10 +52,16 @@ python3 -m pip install --upgrade myspace-cli
|
|
51
52
|
pip install myspace-cli
|
52
53
|
|
53
54
|
# 安装完成后直接使用
|
54
|
-
space-cli
|
55
|
+
# 请注意命令行的启动文件名(space-cli)和pip包的名字(myspace-cli)不一样
|
56
|
+
# 建议直接运行,可以看到使用菜单
|
57
|
+
space-cli
|
55
58
|
|
56
59
|
# 或以模块方式
|
57
|
-
python3 -m space_cli
|
60
|
+
python3 -m space_cli
|
61
|
+
|
62
|
+
# 如果要使用高级的功能,请使用更复杂的命令行参数,可以运行help
|
63
|
+
space-cli --help
|
64
|
+
|
58
65
|
```
|
59
66
|
|
60
67
|
### 方法2:直接使用
|
@@ -89,7 +96,7 @@ space-cli
|
|
89
96
|
### 基本用法
|
90
97
|
|
91
98
|
```bash
|
92
|
-
#
|
99
|
+
# 分析根目录(默认)- 支持交互式下探分析
|
93
100
|
python3 space_cli.py
|
94
101
|
|
95
102
|
# 分析指定路径
|
@@ -100,6 +107,9 @@ python3 space_cli.py -n 10
|
|
100
107
|
|
101
108
|
# 快捷分析当前用户目录(含用户目录深度分析)
|
102
109
|
python3 space_cli.py --home
|
110
|
+
|
111
|
+
# 交互式目录空间分析(支持选择序号下探,选择0返回上一级)
|
112
|
+
python3 space_cli.py --directories-only
|
103
113
|
```
|
104
114
|
|
105
115
|
### 高级用法
|
@@ -182,21 +192,30 @@ python3 space_cli.py --big-files --export report.json
|
|
182
192
|
建议: 磁盘空间不足,建议清理一些文件
|
183
193
|
```
|
184
194
|
|
185
|
-
###
|
195
|
+
### 交互式目录分析
|
186
196
|
```
|
187
197
|
============================================================
|
188
198
|
📊 占用空间最大的目录
|
189
199
|
============================================================
|
190
200
|
显示前 20 个最大的目录:
|
191
201
|
|
192
|
-
1. /Applications
|
193
|
-
大小:
|
202
|
+
1. /Applications -- 大小: 15.2 GB (3.04%)
|
203
|
+
2. /Users/username/Library -- 大小: 8.5 GB (1.70%)
|
204
|
+
3. /System -- 大小: 6.8 GB (1.36%)
|
194
205
|
|
195
|
-
|
196
|
-
|
206
|
+
============================================================
|
207
|
+
🔍 下探分析选项
|
208
|
+
============================================================
|
209
|
+
选择序号进行深度分析,选择0返回上一级,直接回车退出:
|
210
|
+
请输入选择 [回车=退出]: 1
|
197
211
|
|
198
|
-
|
199
|
-
|
212
|
+
🔍 正在分析: /Applications (15.2 GB)
|
213
|
+
============================================================
|
214
|
+
📊 占用空间最大的目录
|
215
|
+
============================================================
|
216
|
+
1. /Applications/Xcode.app -- 大小: 8.2 GB (1.64%)
|
217
|
+
2. /Applications/Docker.app -- 大小: 3.1 GB (0.62%)
|
218
|
+
3. /Applications/Visual Studio Code.app -- 大小: 1.8 GB (0.36%)
|
200
219
|
```
|
201
220
|
|
202
221
|
### 大文件分析
|
@@ -257,12 +276,13 @@ python3 mcp_server.py
|
|
257
276
|
|
258
277
|
## 性能优化
|
259
278
|
|
260
|
-
-
|
261
|
-
-
|
262
|
-
-
|
263
|
-
-
|
264
|
-
|
265
|
-
|
279
|
+
- **优先使用 `du -sk` 命令**:在 macOS 上使用原生 `du` 命令快速获取目录大小
|
280
|
+
- **智能回退机制**:当 `du` 命令失败时,自动回退到基于 `os.scandir` 的高效遍历
|
281
|
+
- **跳过系统目录**:自动忽略 `/System`、`/Volumes`、`/private` 等系统目录
|
282
|
+
- **跳过无法访问的文件**:自动处理权限错误和符号链接
|
283
|
+
- **支持中断操作**:使用 Ctrl+C 随时中断分析
|
284
|
+
- **内存优化遍历**:使用栈式迭代替代递归,避免深度目录的栈溢出
|
285
|
+
- **单行滚动进度**:避免输出刷屏,使用 ANSI 清行(\r\033[K)避免长行残留
|
266
286
|
|
267
287
|
## 故障排除
|
268
288
|
|
@@ -321,7 +341,14 @@ MIT License
|
|
321
341
|
- 单行滚动进度显示
|
322
342
|
|
323
343
|
### v1.2.0
|
324
|
-
-
|
344
|
+
- 应用分析支持"按序号一键删除应用",并显示将删除的路径清单与预计释放空间
|
325
345
|
- 删除过程增加权限修复与降级清理策略(chflags nouchg / chmod 0777 / 逐项清理)
|
326
346
|
- 针对 "Operation not permitted" 增加友好提示(SIP、完全磁盘访问、退出相关应用)
|
327
347
|
- 单行覆盖输出加入 ANSI 清行,避免长行残留
|
348
|
+
|
349
|
+
### v1.3.0
|
350
|
+
- **性能大幅优化**:优先使用 `du -sk` 命令获取目录大小,失败时回退到 `os.scandir` 高效遍历
|
351
|
+
- **交互式下探分析**:支持选择序号进行深度目录分析,选择0返回上一级
|
352
|
+
- **增强系统信息**:显示 CPU、内存、GPU、硬盘等完整硬件信息
|
353
|
+
- **智能目录过滤**:自动忽略系统目录(`/System`、`/Volumes`、`/private`)
|
354
|
+
- **优化用户体验**:改进菜单选项,支持交互式目录空间分析
|
@@ -154,20 +154,48 @@ class SpaceAnalyzer:
|
|
154
154
|
return f"{bytes_value:.1f} PB"
|
155
155
|
|
156
156
|
def get_directory_size(self, path: str) -> int:
|
157
|
-
"""
|
158
|
-
|
157
|
+
"""高性能计算目录大小。
|
158
|
+
|
159
|
+
优先使用 macOS 的 du -sk(以 KiB 为单位,速度快,原生命令可处理边界情况),
|
160
|
+
若 du 调用失败则回退到基于 os.scandir 的非递归遍历实现(避免 os.walk 的函数调用开销)。
|
161
|
+
"""
|
162
|
+
# 优先尝试 du -sk(BSD du 在 macOS 可用)。
|
159
163
|
try:
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
# 跳过无法访问的目录
|
164
|
+
# du 输出形如: "<kib>\t<path>\n"
|
165
|
+
result = subprocess.run([
|
166
|
+
'du', '-sk', path
|
167
|
+
], capture_output=True, text=True, check=True)
|
168
|
+
out = result.stdout.strip().split('\t', 1)[0].strip()
|
169
|
+
kib = int(out)
|
170
|
+
return kib * 1024
|
171
|
+
except Exception:
|
172
|
+
# du 不可用或失败时回退到 Python 实现
|
170
173
|
pass
|
174
|
+
|
175
|
+
total_size = 0
|
176
|
+
# 基于栈的迭代遍历,避免递归栈与 os.walk 的额外开销
|
177
|
+
stack = [path]
|
178
|
+
while stack:
|
179
|
+
current = stack.pop()
|
180
|
+
try:
|
181
|
+
with os.scandir(current) as it:
|
182
|
+
for entry in it:
|
183
|
+
# 跳过符号链接,避免循环与跨文件系统问题
|
184
|
+
try:
|
185
|
+
if entry.is_symlink():
|
186
|
+
continue
|
187
|
+
if entry.is_file(follow_symlinks=False):
|
188
|
+
try:
|
189
|
+
total_size += entry.stat(follow_symlinks=False).st_size
|
190
|
+
except (OSError, FileNotFoundError, PermissionError):
|
191
|
+
continue
|
192
|
+
elif entry.is_dir(follow_symlinks=False):
|
193
|
+
stack.append(entry.path)
|
194
|
+
except (OSError, FileNotFoundError, PermissionError):
|
195
|
+
continue
|
196
|
+
except (OSError, FileNotFoundError, PermissionError):
|
197
|
+
# 无法进入该目录则跳过
|
198
|
+
continue
|
171
199
|
return total_size
|
172
200
|
|
173
201
|
def analyze_largest_files(self, root_path: str = "/", top_n: int = 50,
|
@@ -241,6 +269,14 @@ class SpaceAnalyzer:
|
|
241
269
|
return [(e["path"], int(e["size"])) for e in cached["entries"]][:top_n]
|
242
270
|
|
243
271
|
print("正在分析目录大小,这可能需要一些时间...")
|
272
|
+
|
273
|
+
# 忽略的目录列表, 这些目录时系统目录,不需要分析
|
274
|
+
ignore_dir_list = [
|
275
|
+
"/System", # 系统目录
|
276
|
+
"/Volumes", # 外部挂载卷
|
277
|
+
"/private", # 私有目录
|
278
|
+
]
|
279
|
+
|
244
280
|
|
245
281
|
directory_sizes = []
|
246
282
|
|
@@ -252,6 +288,9 @@ class SpaceAnalyzer:
|
|
252
288
|
# 跳过隐藏文件和系统文件
|
253
289
|
if item.startswith('.') and item not in ['.Trash', '.localized']:
|
254
290
|
continue
|
291
|
+
|
292
|
+
if item_path in ignore_dir_list:
|
293
|
+
continue
|
255
294
|
|
256
295
|
if os.path.isdir(item_path):
|
257
296
|
try:
|
@@ -284,19 +323,58 @@ class SpaceAnalyzer:
|
|
284
323
|
return []
|
285
324
|
|
286
325
|
def get_system_info(self) -> Dict:
|
287
|
-
"""
|
326
|
+
"""获取系统信息(包括 CPU、内存、GPU、硬盘等硬件信息)"""
|
327
|
+
system_info = {}
|
328
|
+
|
288
329
|
try:
|
289
|
-
#
|
330
|
+
# 获取系统版本信息
|
290
331
|
result = subprocess.run(['sw_vers'], capture_output=True, text=True)
|
291
|
-
system_info = {}
|
292
332
|
for line in result.stdout.split('\n'):
|
293
333
|
if ':' in line:
|
294
334
|
key, value = line.split(':', 1)
|
295
335
|
system_info[key.strip()] = value.strip()
|
336
|
+
except Exception:
|
337
|
+
system_info["ProductName"] = "macOS"
|
338
|
+
system_info["ProductVersion"] = "未知"
|
339
|
+
|
340
|
+
try:
|
341
|
+
# 获取 CPU 信息
|
342
|
+
cpu_result = subprocess.run(['sysctl', '-n', 'machdep.cpu.brand_string'],
|
343
|
+
capture_output=True, text=True)
|
344
|
+
if cpu_result.returncode == 0:
|
345
|
+
system_info["CPU"] = cpu_result.stdout.strip()
|
296
346
|
|
297
|
-
|
347
|
+
# 获取 CPU 核心数
|
348
|
+
cores_result = subprocess.run(['sysctl', '-n', 'hw.ncpu'],
|
349
|
+
capture_output=True, text=True)
|
350
|
+
if cores_result.returncode == 0:
|
351
|
+
system_info["CPU核心数"] = cores_result.stdout.strip()
|
352
|
+
|
353
|
+
except Exception:
|
354
|
+
system_info["CPU"] = "未知"
|
355
|
+
system_info["CPU核心数"] = "未知"
|
356
|
+
|
357
|
+
try:
|
358
|
+
# 获取内存信息
|
359
|
+
mem_result = subprocess.run(['sysctl', '-n', 'hw.memsize'],
|
360
|
+
capture_output=True, text=True)
|
361
|
+
if mem_result.returncode == 0:
|
362
|
+
mem_bytes = int(mem_result.stdout.strip())
|
363
|
+
system_info["内存"] = self.format_bytes(mem_bytes)
|
298
364
|
except Exception:
|
299
|
-
|
365
|
+
system_info["内存"] = "未知"
|
366
|
+
|
367
|
+
|
368
|
+
try:
|
369
|
+
# 获取启动时间
|
370
|
+
boot_result = subprocess.run(['uptime'], capture_output=True, text=True)
|
371
|
+
if boot_result.returncode == 0:
|
372
|
+
uptime_line = boot_result.stdout.strip()
|
373
|
+
system_info["运行时间"] = uptime_line
|
374
|
+
except Exception:
|
375
|
+
system_info["运行时间"] = "未知"
|
376
|
+
|
377
|
+
return system_info
|
300
378
|
|
301
379
|
|
302
380
|
class SpaceCli:
|
@@ -614,12 +692,12 @@ class SpaceCli:
|
|
614
692
|
print(f"建议: \033[36m{message}\033[0m")
|
615
693
|
print()
|
616
694
|
|
617
|
-
def print_largest_directories(self, path: str = "/", top_n: int = 20):
|
695
|
+
def print_largest_directories(self, path: str = "/Library", top_n: int = 20):
|
618
696
|
"""打印占用空间最大的目录"""
|
619
697
|
print("=" * 60)
|
620
698
|
print("📊 占用空间最大的目录")
|
621
699
|
print("=" * 60)
|
622
|
-
|
700
|
+
|
623
701
|
# 若有缓存:直接显示缓存,然后再询问是否重新分析
|
624
702
|
if self.args.use_index:
|
625
703
|
cached = self.index.get(path)
|
@@ -635,6 +713,8 @@ class SpaceCli:
|
|
635
713
|
except EOFError:
|
636
714
|
ans = ""
|
637
715
|
if ans not in ("y", "yes"):
|
716
|
+
# 提供下探分析选项
|
717
|
+
self._offer_drill_down_analysis(cached_entries, path)
|
638
718
|
return
|
639
719
|
else:
|
640
720
|
return
|
@@ -655,6 +735,56 @@ class SpaceCli:
|
|
655
735
|
total_bytes = total_info['total'] if total_info else 1
|
656
736
|
print("\n已重新分析,最新结果:\n")
|
657
737
|
self._render_dirs(directories, total_bytes)
|
738
|
+
|
739
|
+
# 提供下探分析选项
|
740
|
+
self._offer_drill_down_analysis(directories, path)
|
741
|
+
|
742
|
+
def _offer_drill_down_analysis(self, directories: List[Tuple[str, int]], current_path: str) -> None:
|
743
|
+
"""提供交互式下探分析选项"""
|
744
|
+
if not sys.stdin.isatty() or getattr(self.args, 'no_prompt', False):
|
745
|
+
return
|
746
|
+
|
747
|
+
print("\n" + "=" * 60)
|
748
|
+
print("🔍 下探分析选项")
|
749
|
+
print("=" * 60)
|
750
|
+
print("选择序号进行深度分析,选择0返回上一级,直接回车退出:")
|
751
|
+
|
752
|
+
try:
|
753
|
+
choice = input("请输入选择 [回车=退出]: ").strip()
|
754
|
+
except EOFError:
|
755
|
+
return
|
756
|
+
|
757
|
+
if not choice:
|
758
|
+
return
|
759
|
+
|
760
|
+
try:
|
761
|
+
idx = int(choice)
|
762
|
+
except ValueError:
|
763
|
+
print("❌ 无效的输入(应为数字序号)")
|
764
|
+
return
|
765
|
+
|
766
|
+
if idx == 0:
|
767
|
+
# 返回上一级
|
768
|
+
parent_path = os.path.dirname(current_path.rstrip('/'))
|
769
|
+
if parent_path != current_path and parent_path != '/':
|
770
|
+
print(f"\n🔄 返回上一级: {parent_path}")
|
771
|
+
self.print_largest_directories(parent_path, self.args.top_n)
|
772
|
+
else:
|
773
|
+
print("❌ 已在根目录,无法返回上一级")
|
774
|
+
return
|
775
|
+
|
776
|
+
if idx < 1 or idx > len(directories):
|
777
|
+
print("❌ 序号超出范围")
|
778
|
+
return
|
779
|
+
|
780
|
+
selected_path, selected_size = directories[idx - 1]
|
781
|
+
size_str = self.analyzer.format_bytes(selected_size)
|
782
|
+
|
783
|
+
print(f"\n🔍 正在分析: {selected_path} ({size_str})")
|
784
|
+
print("=" * 60)
|
785
|
+
|
786
|
+
# 递归调用下探分析
|
787
|
+
self.print_largest_directories(selected_path, self.args.top_n)
|
658
788
|
|
659
789
|
def print_app_analysis(self, top_n: int = 20):
|
660
790
|
"""打印应用目录占用分析,并给出卸载建议"""
|
@@ -765,7 +895,7 @@ class SpaceCli:
|
|
765
895
|
system_info = self.analyzer.get_system_info()
|
766
896
|
|
767
897
|
for key, value in system_info.items():
|
768
|
-
print(f"{key}: {value}")
|
898
|
+
print(f"{key}: \033[36m{value}\033[0m")
|
769
899
|
print()
|
770
900
|
|
771
901
|
def export_report(self, output_file: str, path: str = "/"):
|
@@ -964,13 +1094,13 @@ def main():
|
|
964
1094
|
print("🧭 SpaceCli 菜单(直接回车 = 执行全部项目)")
|
965
1095
|
print("=" * 60)
|
966
1096
|
home_path = str(Path.home())
|
967
|
-
print("1) \033[36m
|
1097
|
+
print("1) \033[36m执行主要项目(系统信息 + 健康 + 应用)\033[0m")
|
968
1098
|
print(f"2) \033[36m当前用户目录分析(路径: {home_path})\033[0m")
|
969
1099
|
print("3) \033[36m仅显示系统信息\033[0m")
|
970
1100
|
print("4) \033[36m仅显示磁盘健康状态\033[0m")
|
971
|
-
print("5) \033[36m
|
972
|
-
print("6) \033[36m
|
973
|
-
print("7) \033[36m
|
1101
|
+
print("5) \033[36m交互式目录空间分析\033[0m")
|
1102
|
+
print("6) \033[36m仅分析程序应用目录空间\033[0m")
|
1103
|
+
print("7) \033[36m仅进行大文件分析(很耗时,可随时终止)\033[0m")
|
974
1104
|
print("0) \033[36m退出\033[0m")
|
975
1105
|
try:
|
976
1106
|
choice = input("请选择 [回车=1]: ").strip()
|
@@ -985,27 +1115,34 @@ def main():
|
|
985
1115
|
args.health_only = False
|
986
1116
|
args.directories_only = False
|
987
1117
|
elif choice == "3": # 仅显示系统信息
|
988
|
-
args.health_only =
|
1118
|
+
args.health_only = False
|
989
1119
|
args.directories_only = False
|
990
1120
|
args.apps = False
|
1121
|
+
args.big_files = False
|
991
1122
|
elif choice == "4": # 仅显示磁盘健康状态
|
992
|
-
args.health_only =
|
993
|
-
args.directories_only =
|
1123
|
+
args.health_only = True
|
1124
|
+
args.directories_only = False
|
994
1125
|
args.apps = False
|
1126
|
+
args.big_files = False
|
995
1127
|
elif choice == "5": # 仅显示最大目录列表
|
996
1128
|
args.health_only = False
|
997
|
-
args.directories_only =
|
1129
|
+
args.directories_only = True
|
998
1130
|
args.apps = False
|
1131
|
+
args.big_files = False
|
999
1132
|
elif choice == "6": # 仅显示应用目录分析与建议
|
1000
1133
|
args.health_only = False
|
1001
1134
|
args.directories_only = False
|
1002
1135
|
args.apps = True
|
1136
|
+
args.big_files = False
|
1003
1137
|
elif choice == "7": # 仅显示大文件分析
|
1004
1138
|
args.health_only = False
|
1005
|
-
args.directories_only =
|
1139
|
+
args.directories_only = False
|
1006
1140
|
args.apps = False
|
1007
1141
|
args.big_files = True
|
1008
1142
|
else: # 默认执行全部(用户不选择,或者选择1)
|
1143
|
+
args.health_only = True
|
1144
|
+
args.directories_only = False
|
1145
|
+
args.big_files = False
|
1009
1146
|
args.apps = True
|
1010
1147
|
|
1011
1148
|
|
@@ -1025,15 +1162,14 @@ def main():
|
|
1025
1162
|
|
1026
1163
|
try:
|
1027
1164
|
# 显示系统信息
|
1028
|
-
|
1029
|
-
space_cli.print_system_info()
|
1165
|
+
space_cli.print_system_info()
|
1030
1166
|
|
1031
1167
|
# 显示磁盘健康状态
|
1032
|
-
if
|
1168
|
+
if args.health_only:
|
1033
1169
|
space_cli.print_disk_health(args.path)
|
1034
1170
|
|
1035
1171
|
# 显示目录分析
|
1036
|
-
if
|
1172
|
+
if args.directories_only or args.path !='/':
|
1037
1173
|
space_cli.print_largest_directories(args.path, args.top_n)
|
1038
1174
|
# 若分析路径为当前用户目录,做深度分析
|
1039
1175
|
if os.path.abspath(args.path) == os.path.abspath(str(Path.home())):
|
@@ -1044,7 +1180,8 @@ def main():
|
|
1044
1180
|
space_cli.print_app_analysis(args.top_n)
|
1045
1181
|
|
1046
1182
|
# 大文件分析
|
1047
|
-
if getattr(args, 'big_files', False):
|
1183
|
+
#if getattr(args, 'big_files', False):
|
1184
|
+
if args.big_files:
|
1048
1185
|
space_cli.print_big_files(args.path, top_n=args.big_files_top, min_size_bytes=args.big_files_min_bytes)
|
1049
1186
|
|
1050
1187
|
# 导出报告
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|