1. 先搞清楚:Windows 下为什么要折腾 tree 命令
很多人第一次接触tree是在 Linux 服务器上,敲一下,目录结构像树一样铺开,一眼就能看清整个项目的骨架。等回到 Windows 上想复刻这个操作,才发现事情没那么简单:系统里确实有个同名命令,但用起来总觉得差点意思。于是就有了"在 Windows 上全局安装 tree 命令"这个需求——所谓全局安装,说白了就是让tree这三个字母在任意目录、任意终端窗口里都能直接敲出来,而不是每次都要cd到某个文件夹再双击 exe。
这件事看着小,背后牵扯的东西不少:环境变量怎么配、PATH 的查找顺序是什么、系统自带的tree.com会不会把你的新程序顶掉、中文目录输出会不会变乱码。这些坑我基本都踩过一遍,所以这篇就把整个流程从"为什么要做"到"怎么做"再到"出问题怎么查"完整串一遍。不管你是刚学会打开 CMD 的新手,还是天天写脚本的老手,照着走都能搞定。
1.1 tree 到底解决了什么问题
日常开发和运维里,有大量场景需要"把目录结构可视化"。比如接手一个陌生的老项目,你要先摸清楚代码怎么组织的;比如写 README 文档,需要给读者展示项目文件树;比如排查"这个磁盘空间到底被谁吃了",需要快速罗列深层目录;再比如给同事交接资料,得附一份完整的目录清单。
这些需求如果靠手动画,效率低到离谱。Windows 资源管理器倒是有树形视图,但它不能导出、不能过滤、不能控制深度,更没法塞进脚本里自动化。而tree命令一行就能输出纯文本结构,可以直接重定向到文件、可以复制进文档、可以被其他脚本读取。这就是它的价值——把文件系统的层级关系转换成机器友好、人也可读的文本。
1.2 Windows 自带 tree 与 GNU tree 的差距
Windows 确实自带了一个tree,位置在C:\Windows\System32\tree.com。注意后缀是.com不是.exe,这点后面会讲到,它直接影响你的安装策略。这个自带版本能用,但功能相当寒酸,和 Linux 上那个 GNU tree 比起来差距明显。
| 能力项 | Windows 自带 tree | GNU tree |
|---|---|---|
| 控制展开深度 | 不支持 | 支持-L 2指定层数 |
| 排除指定目录 | 不支持 | 支持-I "node_modules" |
| 只显示目录不显示文件 | 不支持 | 支持-d |
| 只列出匹配的文件 | 不支持 | 支持-P "*.md" |
| 输出 JSON / XML / HTML | 不支持 | 支持-J、-X、-H |
| 显示文件大小 | 不支持 | 支持--du -h |
| 彩色高亮 | 不支持 | 支持-C |
| 输出到文件 | 靠重定向 | 支持-o 文件名 |
差距最要命的是过滤和深度控制。你去看一个node_modules有三万个子目录的项目,自带tree /F能把终端刷爆,而 GNU tree 一句tree -I "node_modules" -L 3就干净利落。所以值得花十分钟装一下。
1.3 三条安装路线的取舍
在 Windows 上让tree全局可用,实际有三条路:
- 手动放单文件 exe + 配环境变量。最原始,但最可控,不依赖任何包管理器,离线机器也能用。
- 用包管理器安装(winget / scoop / chocolatey)。一条命令搞定,升级方便,但前提是机器上得先有这些工具。
- 从源码编译。真没必要,除非企业环境有严格的安全审计要求,不允许下载来源不明的二进制。
我的建议是:个人机器走包管理器,公司受限机器走手动方案。下面两条路我都会详细写,你按自己的场景选。
2. 全局安装的底层逻辑:PATH 是怎么找到你的命令的
在动手之前,花三分钟搞懂 PATH 的查找机制,能帮你省下后面一小时的抓瞎时间。很多人装东西失败,不是步骤错了,而是根本没理解系统在背后做了什么。
2.1 从敲下 tree 到程序跑起来,中间发生了什么
当你在 CMD 或 PowerShell 里敲下tree并回车,系统并不是在全盘搜索这个文件(那样太慢了)。它的流程大致是这样:
- 先看当前目录下有没有
tree这个可执行文件; - 如果没有,就按PATH 环境变量里列出的目录顺序,一个一个去翻;
- 翻到第一个匹配的文件就执行,后面的目录不再看;
- 全都翻完还没找到,就报那句经典错误:
'tree' 不是内部或外部命令,也不是可运行的程序或批处理文件。
关键点在第三步:第一个匹配到的就是赢家,PATH 的顺序决定一切。这就埋下了本节最重要的坑,我们在 2.3 里详细说。
另一个细节是文件扩展名。Windows 有个PATHEXT环境变量,默认值大概是:
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC意思是,当你在同一个目录里同时存在tree.com和tree.exe时,系统会优先选.COM,因为它在列表里排第一。而系统自带的那个恰好就是C:\Windows\System32\tree.com。这就是为什么很多人把 GNU 的 tree.exe 复制进 System32 之后,敲 tree 出来的还是老界面——不是你装错了,是.com被优先执行了。
2.2 用户变量还是系统变量,这是个问题
Windows 的环境变量分两层:用户变量和系统变量。
- 改用户变量:只对你当前这个账户生效,不需要管理员权限,最安全。
- 改系统变量:对机器上所有账户生效,需要管理员权限,改错了可能影响别的软件。
实际生效时的 PATH,是"系统 PATH 在前,用户 PATH 在后"拼接起来的。这一点非常关键,因为它意味着你在用户变量里加的目录,永远排在 System32 后面,也就永远抢不过系统自带的tree.com。
那怎么办?三条路,后面第 3 章会展开,这里先给结论:
- 给你的 GNU tree 改个名,比如叫
gtree.exe,从此零冲突,这是最省心的; - 在 PowerShell 里用函数覆盖,因为 PowerShell 的命令优先级是"别名 > 函数 > 内置命令 > 外部程序",函数能压过
tree.com; - 把工具目录塞进系统 PATH 并排在
%SystemRoot%\System32前面,能生效但有点脏,不太推荐。
注意:怀疑 PATH 被污染时,别急着清空重配。先把当前值导出备份(
echo %PATH% > path_backup.txt),改坏了还能还原。这个习惯救过我不止一次。
2.3 为什么"我明明配了却用不了"
我见过最多的三种失败情形,几乎都出在理解偏差上。
第一种,配完没重开终端。环境变量是在进程启动时读入的,已经开着的 CMD 窗口不会自动刷新。必须关掉重开,或者重启资源管理器让新窗口继承新环境。
第二种,路径写错。比如你填的是文件夹路径,却手滑写成了 exe 的完整路径;或者路径里带空格没加引号;再或者复制的时候把中文全角引号也带进去了。判断方法很简单,在 CMD 里执行where tree,它会把所有能匹配到的位置列出来,一眼就知道哪条 PATH 生效了。
第三种,也是最隐蔽的——被系统自带的同名程序顶掉了。你在 PATH 里加了C:\Tools\bin,敲tree却还是老样子,where tree一看,返回的是C:\Windows\System32\tree.com,而你的目录排在后面。这不是配置失败,是顺序问题。
# PowerShell 里查看命令到底解析到了哪个文件 Get-Command tree | Select-Object Name, CommandType, Source这个命令输出里的Source字段就是答案。养成习惯,装完任何命令行工具,先跑一次Get-Command,比重开十次终端都快。
3. 手动方案实操:把 tree.exe 变成随叫随到的命令
手动方案适合不方便装包管理器的机器,或者你只想放一个文件进去、不想引入任何额外依赖。整个流程分四步:找文件、定目录、配 PATH、验证。
3.1 找一个可信的 tree.exe
GNU tree 本身是开源项目,社区里有好人把它编译成了 Windows 原生单文件版本,不需要任何运行库,双击就能跑。搜索时认准两个特征:单文件、原生编译(native port),而不是那种需要装 Cygwin 或 MSYS2 才能跑的版本。
如果你所在的环境对下载来源有严格规定,那就别走这条路,直接跳到第 4 章用包管理器,或者让运维从源码构建。企业机器上安全合规永远排在方便前面,这个不用犹豫。
拿到文件后先别急着放,双击运行一下(可以直接在 CMD 里.\tree.exe --version),确认能看到版本号输出。能看到版本号,说明文件本身没坏、架构也匹配。
提示:32 位和 64 位系统都能跑 32 位版本,但 64 位系统跑 64 位版本性能更好。如果不确定自己系统位数,
echo %PROCESSOR_ARCHITECTURE%输出AMD64就是 64 位。
3.2 放哪里最合适:目录规划
这是最容易被随便对待的一步,但恰恰影响后续维护。我给你三种选择,按推荐程度排序。
推荐:专门的工具目录。比如C:\Tools\bin,或者在用户目录下建一个%USERPROFILE%\bin。所有你自己装的小工具都往里扔,PATH 里只加这一个目录,以后加新工具不用再改环境变量。这种方式不需要管理员权限,重装系统前备份这个目录就行。
次选:C:\Windows\System32。好处是它本来就在 PATH 里,不用配环境变量。坏处是需要管理员权限,而且会和其他系统文件混在一起,时间久了根本分不清哪些是自己塞的。另外如 2.1 所说,即使你把tree.exe放进去,.com版本依然优先,等于白干。
不推荐:随便丢在某个项目目录里。这样只有cd到那个目录才能用,完全谈不上全局。
:: 建目录并把文件放进去,命令行方式 mkdir C:\Tools\bin copy tree.exe C:\Tools\bin\建好之后,建议先把C:\Tools\bin加进环境变量,再把文件复制进去,这样顺序上更符合直觉(其实先复制后配也一样,只是先配 PATH 方便报错时排查是哪一步出的问题)。
3.3 配置环境变量的完整步骤
图形界面操作路径如下,Windows 10 和 Windows 11 基本一致:
- 按
Win + R,输入sysdm.cpl回车,打开"系统属性"; - 切到"高级"选项卡,点右下角的"环境变量"按钮;
- 上半部分是用户变量,下半部分是系统变量。选哪个上面已经分析过,这里以用户变量为例;
- 在用户变量区域找到
Path,选中后点"编辑"; - 点"新建",粘贴
C:\Tools\bin,注意不要带引号,结尾也不要加反斜杠; - 一路点"确定"退出。
有两个细节要特别注意。第一,路径里绝对不要有中文和空格,虽然 Windows 现在能处理,但某些工具链在解析时会出幺蛾子,比如空格被截断成两个条目,导致你的C:\Program和Files\bin各占一行,全是废条目。第二,Windows 10 之前的环境变量编辑框是一个长字符串,一格一格用分号隔开,手动编辑极易弄错;Win10 之后变成了列表形式,一条一行,好很多。如果你的系统还是老样式,强烈建议用 PowerShell 命令改:
# 读取当前用户 PATH,追加目录,再写回(注意保留原有内容) $old = [Environment]::GetEnvironmentVariable("Path", "User") $new = $old + ";C:\Tools\bin" [Environment]::SetEnvironmentVariable("Path", $new, "User")用命令改的好处是不会漏掉分隔符,也不容易误删。改之前先echo $old看一眼,确认拿到的是完整值再写回。
3.4 验证安装是否成功
配置完成后,关掉所有已打开的终端窗口,重新打开一个 CMD,依次执行:
where tree tree --version tree -L 2第一句确认路径能不能被找到。如果输出里有C:\Tools\bin\tree.exe这一行,恭喜,PATH 配置生效了。如果只有C:\Windows\System32\tree.com,说明你的目录没生效或者排在了后面,回到 2.3 排查。
第二句确认程序能跑起来并打印版本号。第三句是个实际的深度控制测试,如果输出的是漂亮的分层结构,且只展开了两层,说明你用的确实是 GNU 版本。
如果想让tree这个名字真正被你的程序占用,前面提过三种办法。我在自己机器上用的最简单粗暴的一种——直接改名:
copy C:\Tools\bin\tree.exe C:\Tools\bin\gtree.exe以后需要 GNU 版本就敲gtree,需要系统自带的就敲tree,两个共存,互不影响,永远不会搞混。说实话,比折腾 PATH 顺序省心多了。
4. 用包管理器一条命令搞定:三种工具横向对比
如果你手上这台机器已经装了 winget、scoop 或者 chocolatey 中的任何一个,那事情就简单了——一条命令的事。下面分别说,最后给个对比表帮你选。
4.1 winget:系统自带的现代选择
Windows 10 21H2 之后的版本和 Windows 11 都自带 winget(App Installer)。先确认一下:
winget --version有输出就可以直接用。然后搜索:
winget search tree搜索结果里会混进TreeSize之类的 GUI 工具,你要找的是纯粹的命令行 tree。如果列表里有,直接装:
winget install --id <搜到的包ID>winget 的优势是系统自带、不需要额外安装任何东西,装完自动处理 PATH,不需要你手动配。缺点是包源里不一定有你要的那个 tree 版本,搜不到就换下面的方案。
注意:winget 安装有时会因为网络原因卡在下载阶段,这是很常见的现象。这时候别反复重试,先换个思路,用 4.2 或 4.3 的方案,或者回到第 3 章的手动方案。
4.2 scoop:免管理员权限的轻量路线
scoop 的最大特点是把所有软件装在用户目录下(默认%USERPROFILE%\scoop),全程不需要管理员权限,特别适合受管控的公司电脑。
首次安装 scoop 需要先设置 PowerShell 的执行策略,然后运行官方安装脚本:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser irm get.scoop.sh | iex如果提示权限问题,可以加一个"仅当前用户安装"的参数:
irm get.scoop.sh -OutFile 'install.ps1' .\install.ps1 -ScoopDir "$env:USERPROFILE\scoop"装好之后:
scoop search tree scoop install treescoop 会把程序放进scoop\shims目录并通过垫片(shim)机制转发调用,所以安装完立刻就能用,不需要重启终端。它的另一个好处是升级和卸载都干净:scoop update tree和scoop uninstall tree,不会往注册表里乱七八糟地写东西。
4.3 chocolatey:老牌方案,适合已经有它的机器
chocolatey 是 Windows 上资历最老的包管理器,需要管理员权限的 PowerShell。安装命令是:
Set-ExecutionPolicy Bypass -Scope Process -Force choco search tree --exact choco install tree -y它把软件装在C:\ProgramData\chocolatey下,全局生效,所有用户可用。缺点是社区仓库里的包质量参差不齐,同名包可能有好几个变体,装之前最好看一眼包详情里的描述。
如果你的机器上本来就有 chocolatey(很多运维脚本会预装),那就直接用它,没必要再引入 scoop,工具越多维护成本越高。
4.4 三种方式对比与选择建议
| 对比项 | winget | scoop | chocolatey |
|---|---|---|---|
| 是否需要额外安装 | 否,系统自带 | 是 | 是 |
| 是否需要管理员权限 | 视安装范围而定 | 否 | 是 |
| 安装位置 | 系统目录 | 用户目录 | C:\ProgramData |
| 卸载干净程度 | 较好 | 很好 | 一般 |
| 包源里是否有 tree | 需要实测搜索 | 通常有 | 通常有 |
| 升级体验 | winget upgrade | scoop update | choco upgrade |
| 适合场景 | 个人新机器 | 公司受限电脑 | 已有运维体系 |
我的实际选择顺序是:先winget search,搜不到再用 scoop,都没有就手动。chocolatey 只在机器上已经有了的情况下才考虑,为装一个小工具而引入一整套 choco 体系,性价比不高。
5. tree 的实战用法:参数、乱码与输出技巧
装好了不用起来等于白装。这一章把我日常最常用的几组参数和场景整理出来,都是实战中反复验证过的。
5.1 高频参数速查
先给一张表,再逐个展开最常用的几个。
| 参数 | 作用 | 典型场景 |
|---|---|---|
-L n | 只展开 n 层目录 | 项目太大,先看骨架 |
-d | 只显示目录 | 分析目录结构,忽略文件 |
-a | 显示隐藏文件 | 排查.gitignore之类的隐藏项 |
-I 模式 | 排除匹配的目录/文件 | 排除node_modules、.git |
-P 模式 | 只显示匹配的文件 | 只看*.md文档 |
-f | 显示完整路径前缀 | 需要复制路径时 |
-h | 人类可读的文件大小 | 配合--du用 |
--du | 累计目录大小 | 找占空间的大目录 |
-o 文件 | 输出到指定文件 | 生成文档素材 |
--filelimit n | 目录条目超过 n 就不再展开 | 避免输出爆炸 |
实际最常用的组合,我总结下来是三个:
:: 场景一:快速看项目骨架,屏蔽依赖目录,只看三层 gtree -L 3 -I "node_modules|.git|dist|build" :: 场景二:只看目录,不看文件,适合分析磁盘结构 gtree -d -L 4 :: 场景三:找出哪些目录最占空间 gtree -d --du -h -L 2场景一是我接手新项目时的第一刀,一条命令就能看明白这个仓库的组织方式,比在 IDE 里一层层点快得多。场景三在排查"磁盘满了"的时候特别好用,直接定位到最肥的那几个目录。
提示:
-I后面的模式支持用|连接多个,并且匹配的是目录名而不是完整路径。所以-I "node_modules"会排除所有层级的同名目录,效果正合心意。
5.2 输出到文件:生成项目结构文档
写 README 的时候我最常做的一件事,就是把目录树导出成文本,粘进文档里。两种方式:
:: 方式一:用 -o 参数直接输出 gtree -L 3 -I "node_modules|.git|.vscode" -o structure.txt :: 方式二:用重定向 gtree -L 3 -I "node_modules|.git" > structure.txt这里有个实战经验:生成文档用的树,一定要加-L限制深度,并且排除掉所有自动生成的目录。我第一次导出的时候没限制,结果node_modules和.git加起来刷了八千多行,粘贴到文档里直接把编辑器卡死了。后来固定用-L 3加排除模式,输出基本稳定在五十行以内,阅读体验好很多。
再进阶一点,如果你要的是给程序读的结构数据,而不是给人看的文本,可以用 JSON 输出:
gtree -J -L 3 > structure.jsonJSON 格式能被脚本直接解析,比如写个 Python 脚本统计每个目录下的文件数量、生成可视化的目录统计报表,都很方便。这是我后来处理大型仓库时的标配做法。
5.3 中文乱码与编码处理
这是 Windows 上最经典的坑。GNU tree 输出的是 UTF-8 字节流,而 CMD 默认的代码页往往是 936(GBK),两者对不上,中文目录名就变成一堆问号或方块。
解决办法是先把终端代码页切到 UTF-8:
chcp 65001 gtree -L 2输出立刻正常。如果重定向到文件,也要在切了代码页之后再执行:
chcp 65001 gtree -L 3 > structure.txtPowerShell 里情况稍有不同,它有自己的输出编码设置。用管道写文件时可以显式指定:
gtree -L 3 | Out-File -Encoding utf8 structure.txt要提醒的是,不同来源编译的 tree.exe,输出编码行为可能不一样。有的版本会自动适配当前代码页,有的则死死输出 UTF-8,还有的会输出 UTF-16。所以如果切了代码页还是乱码,别怀疑人生,换一种组合再试一次就行:chcp 936配重定向、chcp 65001配重定向,两个组合里总有一个是对的。用记事本打开输出文件看一眼,正常显示就是成功。
顺便说一句,Windows 自带的tree.com在这方面反而省心,因为它始终用系统本地代码页输出,中文从来不错乱。所以如果你只是偶尔需要导出中文目录结构,tree /F /A > list.txt其实够用了。GNU 版本的价值主要在于过滤和格式控制。
5.4 结合重定向做二次筛选
tree的输出是纯文本,这意味着它可以和 Windows 上的文本处理命令组合使用。举几个我常用的例子:
:: 找出输出里所有包含 "test" 的行 gtree -L 5 | findstr /i "test" :: 统计某个项目一共有多少个目录 gtree -d -L 10 | find /c /v "" :: 找出深度超过三层的路径(通过缩进量判断) gtree -L 8 | findstr /r "^.........."第一条在排查"测试文件都放在哪"的时候很有用。第二条能快速给出规模感——一个项目有 200 个目录还是 2000 个目录,是完全不同的维护难度。
不过说实话,比起这些命令行花活,我更推荐把 tree 的输出存成文件,然后丢进编辑器里用搜索功能慢慢看,效率反而更高。
6. 踩坑记录与排查速查表
前面几章把原理和流程都讲完了,这一章专门收录实际操作中遇到的各种幺蛾子。这些问题单看都不难,但临时遇到的时候最容易卡住。
6.1 常见问题速查表
| 现象 | 大概率原因 | 处理办法 |
|---|---|---|
'tree' 不是内部或外部命令 | PATH 没配或没生效 | 重开终端;用where tree确认 |
where tree只返回 System32 | 系统自带版本优先级更高 | 改名 gtree,或用 PowerShell 函数覆盖 |
| 装完敲 tree 还是老界面 | .com扩展名优先级高于.exe | 同上,别把 exe 放 System32 |
| 中文目录显示成问号 | 代码页与输出编码不匹配 | chcp 65001或改重定向编码 |
| 输出到一半就没了 | 终端缓冲区太小 | 用-o参数直接写文件 |
| 输出刷屏停不下来 | 没有限制深度和排除目录 | 加-L和-I参数 |
| 复制到 System32 提示被拒绝 | 需要管理员权限 | 用管理员终端,或改放用户目录 |
| 双击 exe 闪一下就消失 | 命令行程序本来就没有窗口 | 正常现象,在终端里调用 |
| 杀软报毒 | 单文件 exe 常见误报 | 走包管理器,或按公司策略走审批 |
6.2 几个容易被忽略的细节
第一,环境变量改动后,已经打开的编辑器内置终端不会自动刷新。VS Code 里的集成终端是从编辑器主进程继承的环境,你得完全退出 VS Code 再重新打开,而不只是关掉终端面板重建一个。这个坑我卡了半小时才反应过来,一度以为 PATH 配错了。
第二,PATH 条目里的尾部分号会制造空条目。空条目在 Windows 上的含义是"当前目录",理论上会影响命令解析,虽然后果通常不严重,但属于隐患。编辑完环境变量后,用echo %PATH%看一遍,确认没有连续的;;。
第三,用户名带中文或空格时,用户目录下的 bin 要慎用。比如%USERPROFILE%\bin展开后可能是C:\Users\张三\bin,某些老旧的工具在解析 PATH 时会在这个位置出问题。如果你的用户名是中文,直接改用C:\Tools\bin更稳。
第四,不同终端的行为不一致是正常的。CMD、PowerShell 5.1、PowerShell 7、Git Bash、Windows Terminal 里的各个 shell,它们解析命令的规则、读取 PATH 的方式、输出编码的默认值都有差异。所以在 CMD 里能用不代表 PowerShell 里也能用。我的习惯是在常用的那个终端里验证通过就算成功,不去追求所有终端全部一致,那是个无底洞。
第五,别轻易动系统变量里的 PATH。系统 PATH 里有大量操作系统和驱动依赖的路径,误删一条可能导致某些功能莫名其妙失效——比如蓝牙没了、打印机找不到、某个驱动加载失败。要加自己的路径,加在用户变量里,出问题只要把自己的那一条删掉就行,风险可控。
第六,养成where和Get-Command的排查习惯。任何命令行工具"装了但用不了",第一反应不该是重装,而是先问一句"系统到底找到的是哪一个"。这个动作能解决九成的"玄学问题"。
# 一整套排查动作,出问题时依次执行 where.exe tree Get-Command tree -All $env:Path -split ';' | Select-String 'Tools'最后一句会把 PATH 里所有包含Tools的条目列出来,用来确认你加的目录到底在不在、排序在第几位。
6.3 卸载与回滚
装的时候顺手,卸载的时候容易忘。手动方案的回滚很简单:删掉那个 exe 文件,再从环境变量里删掉对应条目,重启终端即可,不留任何痕迹。
包管理器方案回滚更规范:
# scoop scoop uninstall tree # winget winget uninstall <包ID> # chocolatey choco uninstall tree -y我一般在装完之后就把对应的卸载命令记在一个自己的"环境配置笔记"里,包括装了什么、装在哪、怎么卸、为什么装。半年后回头看,这份笔记的价值比什么都高。
我自己在几台机器上来回折腾过好几轮之后,最后固化的做法是:用 scoop 装一份,然后软链或者复制一个gtree.exe到工具目录,这样既享受了包管理器的更新便利,又避免了和系统自带tree.com的命名冲突。生成项目结构文档的时候固定用gtree -L 3 -I "node_modules|.git|dist|.idea|.vscode" -o structure.txt,这一条命令我用了两年多,几乎没改过,导出的结构粘进 README 里干净利落。如果你后续想再往前走一步,可以写个批处理把这条命令包起来,加上日期戳自动输出到docs/目录,每次提交前跑一次,项目结构文档就永远是新的了。