让Windows cmd也能用上彩色ls:三种方案与工程实践 如果你是从 Linux 或 macOS 转到 Windows 上开发大概率会在某一次打开 cmd 时顺手敲下ls然后看到一行冷冰冰的提示“ls 不是内部或外部命令也不是可运行的程序或批处理文件。”那一刻确实很挫败。偏偏日常又要经常列目录、看文件大小、找某个文件总不能每次都记着 Windows 的原生命令dir。更让人不习惯的是就算记住了dir默认输出也是白纸黑字一片目录、可执行文件、普通文件全靠眼睛看。这篇文章想解决的就是这件事让 Windows 的 cmd 也能像 Linux 终端一样敲一个ls就看到彩色的、结构清晰的目录列表。方案会覆盖从零基础到爱折腾的多种层次你可以根据需要选一种用起来。1. 在 cmd 里敲 ls 报错不是 cmd 太弱而是机制不同1.1 cmd 和 Linux Shell 的命令查找机制先说一个扎心的真相ls这个命令在 Windows 原生的 cmd 里从来就不存在。Linux 里的ls要么是/usr/bin/ls要么是/bin/lsshell 在 PATH 环境变量里扫一圈就找到了。cmd 呢cmd 的可执行文件查找走的是 PATH 加 PATHEXT 这套逻辑PATH 里没有 ls.exePATHEXT 里也不认识什么没有扩展名的“ls”所以只能给你弹一行“不是内部或外部命令”。真正扛起“列目录”职责的是dir它是 cmd 的内置命令相当于长在 cmd 壳子里的功能。正因为是内置的你没法把它从 cmd 里拆出来单用也没法靠简单配置让它自己“长成” ls 的样子。更麻烦的是Windows 不像 Linux 那样在交互式 shell 里天然支持一套 alias 机制。Linux 的 bash/zsh 可以轻松写alias lsls --colorautocmd 里只有 doskey 宏它和真正的 alias 行为差别很大后面我会专门讲。所以你在 cmd 里敲 ls 失败不是因为你记错了命令也不是 cmd 太笨而是两个系统的命令行设计思路本来就不一样。想用 ls就得自己想办法把“ls 这个程序”或者“ls 这个命令效果”给搬进来。1.2 彩色 ls 的背后是 ANSI 转义序列要实现彩色 ls得先搞清楚颜色到底是谁画上去的。Linux 终端里目录显示成蓝色、可执行文件显示成绿色并不是终端本身认识“目录”和“文件”的概念而是ls这个程序在输出文件名的时候提前在名字前后插入了 ANSI 转义序列。比如目录可能被包成ESC[01;34m开头、ESC[0m结尾的结构终端看到这段控制码就知道“接下来用蓝色显示”。cmd 原生dir输出里没有这类转义序列所以无论你怎么调 cmd 的窗口配色文件名本身永远是单色的。想把彩色 ls 搬到 cmd需要满足三个条件。第一得有一个支持输出 ANSI 颜色码的 ls 程序。第二运行环境得能解析 ANSI 转义序列。第三ls 得知道自己应该输出颜色也就是--colorauto这类参数要生效。Windows 10 之后的 conhost也就是 cmd 默认的控制台宿主和 Windows Terminal 都已经支持 ANSI 转义序列所以后面两个条件基本是满足的最缺的就是一个“会输出颜色的 ls 程序”。这也是后面几个方案的核心思路找一个能输出颜色的 ls想办法塞进 cmd 里让它跑起来。2. 方案一把 Git 自带的彩色 ls 借给 cmd 用推荐2.1 为什么优先推荐 Git for Windows网上能下载到各种散装的 ls.exe但我强烈不建议直接搞一个孤零零的 exe 扔进 Windows。原因很现实GNU 系的 ls 在 Windows 上运行时通常依赖 Cygwin/MSYS2 运行库你只拷贝一个 ls.exe 出来十有八九会碰到“由于找不到 cygwin1.dll 或 msys-2.0.dll无法继续执行代码”的报错。与其跟 DLL 搏斗不如直接装个 Git for Windows它自带一整套 MSYS2 环境C:\Program Files\Git\usr\bin目录下不仅有 ls.exe还有 cp、mv、grep、find 这些常用 GNU 工具。有人会问我只是想用个 ls装 Git 是不是太小题大做了其实真不会。Windows 上搞开发Git 基本是迟早要装的。装完 Git 就有这个工具箱不开 Bash 也能直接从 cmd 调用等于白嫖了一套 coreutils。而且 Git for Windows 更新频率不错ls 这类工具的兼容性和编码处理会跟着一起维护比你自己维护一个“绿色版 ls”省心太多。2.2 实际操作把 Git\usr\bin 加进 PATH 并测试假设你已经装好了 Git for Windows并且使用默认安装路径。接下来要做的事是把C:\Program Files\Git\usr\bin加进用户 PATH。打开“系统属性 → 环境变量”最快的方式是 WinS 搜索“环境变量”点开“编辑系统环境变量”再点“环境变量”。在“用户变量”里找到 Path双击编辑新建一条填C:\Program Files\Git\usr\bin。如果 Git 装到了别的位置就换成实际路径。注意这里的目录是Git\usr\bin不是Git\cmd也不是Git\bin。Git\cmd下面主要是 git.exe 这类 Git 自带命令Git\bin里是 bash.exe、sh.exe 之类都不适合直接加进 PATH 作为日常工具目录。真正装着 ls.exe 的位置就是usr\bin。如果你更习惯用命令操作可以在 PowerShell 里执行这段脚本它有简单的防重复判断$gitBin C:\Program Files\Git\usr\bin if (Test-Path $gitBin) { $userPath [Environment]::GetEnvironmentVariable(Path, User) if ($userPath -notlike *$gitBin*) { [Environment]::SetEnvironmentVariable(Path, $userPath;$gitBin, User) Write-Host 已添加 $gitBin 到用户 PATH } else { Write-Host PATH 里已经存在跳过 } }配置完 PATH 之后记得新开一个 cmd 窗口别在旧窗口里继续敲。新窗口里先执行where ls如果输出指向C:\Program Files\Git\usr\bin\ls.exe就说明 PATH 生效了。接着执行ls --colorauto -F如果目录名、可执行文件都出现了颜色并且目录后面带/符号那第一步就成功了。为什么这里要手动加--colorauto因为在 Git Bash 里直接敲ls有颜色其实是 Bash 的 profile 里给 ls 设置了 alias。cmd 不加载 Bash 的 profile所以裸ls默认不会输出颜色。-F参数也不是必须的但对 cmd 用户来说目录后面带个/会友好很多一眼就知道哪些是文件夹。顺带一提setx PATH和手动编辑环境变量这种方式容易把用户原有的 PATH 截断或者搞出重复项能用脚本就尽量用脚本。2.3 让 ls 常驻 cmd 的持久化配置AutoRun上面测试完你会发现如果不加参数ls还是不好用。每次手动敲ls --colorauto -F太啰嗦所以要用 doskey 宏把 ls 好好包装一下。doskey 宏只在当前 cmd 会话里有效关掉窗口就没了。想让每次打开 cmd 都自动加载宏得借助 cmd 的 AutoRun 机制。在注册表的HKEY_CURRENT_USER\Software\Microsoft\Command Processor下面新建一个字符串值名字叫AutoRun内容指向一个批处理文件比如C:\Users\你的用户名\.cmdrc.bat。这样每次 cmd 启动时都会先执行这个批处理再进入交互界面。我习惯用下面这段内容作为.cmdrc.batecho off doskey lsls.exe --colorauto -F doskey llls.exe -l --colorauto doskey lals.exe -la --colorauto保存的时候要特别注意编码问题。用记事本或 VS Code 保存批处理文件时尽量用 ANSI 编码不要带 UTF-8 BOM。一旦带上 BOMcmd 把第一行echo off前面的 BOM 字符当成指令一起解析有时候会出现奇怪的行为比如命令没执行完窗口就一闪而过或者提示“系统找不到指定的路径”。这个问题我在配脚本时踩过不少次。AutoRun 还有一个副作用要提醒它不只作用于你手动打开的 cmd 窗口任何调用 cmd 的进程都有可能触发生效。比如某些软件执行cmd /c xxx或者持续集成脚本里用了 cmd都会加载这个批处理。好在这种加载只是定义几个 doskey 宏开销极小基本不会造成问题。真正要避免的是在 AutoRun 里写那些会阻塞的命令例如ping等待、交互式删除提示之类否则所有调用 cmd 的场景都会卡住。3. 方案二不装额外程序用 doskey 给 cmd 加一个 ls“外观别名”3.1 doskey 宏的原理与限制如果你不想装 Git也不想用任何第三方程序那只能硬靠 cmd 自带的机制硬凑一个 ls。底层工具是 doskey。doskey 宏并不是真正创建一个叫 ls.exe 的可执行文件它做的只是在 cmd 读取你输入的命令行时做一次字符串替换。比如你定义doskey lsdir那么每次敲lscmd 实际执行的是dir。这个设计带来了几个限制。第一doskey 宏在批处理脚本里不生效。批处理执行时cmd 不会像交互式命令行那样对每行做宏展开所以如果你在 .bat 文件里写了ls它不会变成dir照样报“不是内部或外部命令”。第二宏的优先级比可执行文件更高。一旦定义了ls宏不管你 PATH 里有没有 ls.execmd 都会优先用宏去替换。这在多种方案叠加使用时需要留意。3.2 利用 PowerShell 中转实现“彩色 ls”纯粹用doskey lsdir或doskey lsdir /b其实是没颜色的解决不了彩色需求。想在不装任何程序的情况下得到彩色输出有一个取巧的办法让 doskey 把 ls 转发给 PowerShell用 PowerShell 的 Get-ChildItem 出图。Windows 自带的 PowerShell 在控制台里列出目录时目录名会以深蓝色显示文件用默认颜色天然就是“半彩色”。宏可以这样写doskey lspowershell -NoProfile -Command Get-ChildItem doskey llpowershell -NoProfile -Command Get-ChildItem -Force | Select-Object Mode,LastWriteTime,Length,Name doskey lapowershell -NoProfile -Command Get-ChildItem -Force这个方案的好处是零安装、代码极少。坏处也很明显每次执行 ls 都要启动一个 PowerShell 进程肉眼能感觉到延迟少说几百毫秒而且你要想控制文件类型颜色基本做不到颜色完全取决于 PowerShell 自身的默认配色和终端主题。加上 PowerShell 会自动给长输出分页或换行体验并不算顺滑。在我看来这个方案适合临时应急、不适合长期日常使用。3.3 自定义 cmd 窗口颜色与 dir 样式的补充技巧既然方案二只是让 PowerShell 中转颜色控制会很弱那有没有其他办法提升 cmd 的整体观感至少可以把 cmd 窗口的默认配色调得舒服一点。cmd 内置的color命令可以改全局前景色和背景色比如color 0A就是黑底淡绿字。但这属于“把所有文字染成一个颜色”不是针对文件类型的高亮。如果你平时用 Windows Terminal 比较多可以在 Windows Terminal 的配置文件里给 cmd Profile 指定一个 colorScheme整体观感会好很多。不过还是要强调这只是终端窗口的背景、前景、提示符颜色发生了变化dir输出的文件名该是单色还是单色。真正想要“目录蓝色、可执行绿色、压缩包红色”这种文件类型区分仍然需要 ls 程序自己输出 ANSI 颜色码。这也再次说明想在 cmd 里获得完整体验绕开真正带颜色的 ls 程序是不太现实的。4. 方案三用 lsd 打造更现代的彩色 ls4.1 lsd / eza 是什么为什么值得试如果说方案一是把 Linux 的经典体验搬过来方案三就是“在经典体验上再做一层现代化改造”。lsd全名 LSDeluxe是一个用 Rust 写的ls替代品它默认就带颜色还支持文件类型图标、Git 分支状态、按目录优先排序、树形展示等功能。和 GNU ls 相比它更像给现代终端用户设计的“彩色目录神器”。另一个选择是 eza它是老牌替代品 exa 的维护分支官方说法是“a modern alternative to ls”。eza 和 lsd 都属于新一代工具速度不错配置方式更贴近现代 CLI 习惯。两者选一个就行我个人更常用 lsd因为它的 Git 状态提示在项目目录里很直观而且 Windows 下的安装路径比较友好。这类工具适合谁如果你喜欢折腾终端、愿意装字体调配色想把 Windows 的 cmd 或 PowerShell 弄出一点“现代化终端”的感觉那一定得试试。4.2 安装方式与 PATH 配置lsd 的安装方式非常多样。Windows 10 以上系统可以直接用 wingetwinget install lsd如果你有 Scoop一条命令也行scoop install lsdChocolatey 用户可以用choco install lsd这三种方式都会帮你把可执行文件放进 PATH 管理的目录里通常不需要手动配 PATH。如果不想用包管理器也可以去 GitHub Releases 页面下载lsd-x.x.x-x86_64-pc-windows-msvc.zip这类压缩包解压后把lsd.exe放到你自己创建的D:\tools\bin或者C:\Users\你的用户名\bin目录下再把那个目录加进用户 PATH。安装完之后新开一个 cmd 窗口执行lsd -l如果出现了一个包含权限、链接数、所属用户、文件大小、修改日期、文件名的列表并且文件类型颜色分明那就说明安装成功。eza 的安装也是同样套路scoop install eza或去 GitHub 下载 exe 都行。4.3 在 cmd 中把 ls / ll / la 绑定到 lsd装好 lsd 之后还需要让ls这个命令真正指向 lsd。方式还是 doskey 加 AutoRun和方案一里的套路一样。我自己的宏定义长这样echo off doskey lslsd.exe --group-directories-first doskey lllsd.exe -l --group-directories-first doskey lalsd.exe -la --group-directories-first doskey treelsd.exe --tree --group-directories-first--group-directories-first的意思是把目录排在前面对大目录来说特别有用。--tree可以直接生成树形结构效果接近 Linux 里的tree命令但输出带颜色比 Windows 自带的 tree 好看不少。lsd 的颜色和图标默认就能用但如果你想深度定制可以在用户目录下创建配置文件夹。lsd 会读取~/.config/lsd/config.yaml和~/.config/lsd/colors.yaml。一个常见的 config.yaml 片段# ~/.config/lsd/config.yaml classic: false blocks: - permission - user - size - date - name icons: theme: fancy date: format: %Y-%m-%d %H:%M sorting: dir-grouping: firstcolors.yaml 可以用来指定文件扩展名和类型对应的颜色写法和 LS_COLORS 类似但更结构化。不过对大多数人来说默认配色已经足够好看不用急着改。这里提醒一点lsd 的图标模式依赖 Nerd Font 字体。如果你在 Windows Terminal 里看到的是一个个方块或问号多半是因为终端字体不是 Nerd Font。去 Nerd Fonts 官网下载一个类似 CaskaydiaCove Nerd Font 或 MesloLGM Nerd Font然后在 Windows Terminal 的配置里把字体改成它图标马上就能正常显示。5. 常见问题与避坑清单从环境变量到中文乱码5.1 where ls 结果不对或 ls 根本找不到这类问题最常出现在改完 PATH 之后。很多人会直接在当前 cmd 窗口里执行where ls发现还是找不到就开始怀疑配置有问题。其实 cmd 的环境变量是启动时读取的你改了 PATH 之后旧窗口不会自动刷新。新开一个 cmd 窗口再看通常就正常了。如果新窗口还是找不到那就要检查where ls的实际搜索顺序。cmd 会按照 PATH 里目录的先后顺序依次查找用户 PATH 中的目录默认排在系统 PATH 后面还是前面取决于变量合并的顺序。有时候用户 PATH 里已经有其他目录里面也放了个 ls.exe比如某些 Python 工具包或者 Anaconda 环境那where ls出来的结果可能不是你想要的。这时候可以用where ls一次性列出所有匹配位置或者直接执行C:\Program Files\Git\usr\bin\ls.exe --version验证完整路径。更隐蔽的坑是“全家桶式 PATH”带来的命令冲突。把Git\usr\bin加进 PATH 之后不只是 ls 进来了find、sort、grep这些 GNU 工具也会被 cmd 看到。Windows 原本自带一个用于字符串搜索的find.exe一旦 usr\bin 排在前面你在批处理里写的find可能就变成 GNU find行为完全不一样。这是个很容易被忽略的副作用如果平时要用 Windows 自带的 find就要注意 PATH 顺序或者在批处理里写完整路径%SystemRoot%\System32\find.exe。5.2 颜色为什么不显示颜色问题我从两个层面排查。首先是终端层面Windows 7 和更老系统的 conhost 对 ANSI 转义序列支持非常差基本别指望 ls 能显示颜色。Windows 10 之后才逐步完善支持Windows 11 的 Terminal 更是全量支持。如果系统太老建议优先装 Windows Terminal别折腾老 conhost 了。第二是 ls 参数层面。GNU ls 的--colorauto只在检测到输出目标是终端时才给颜色一旦你把输出重定向到文件或者通过管道传给其他命令颜色就会自动关闭。这是符合预期的行为不是 bug。如果希望重定向后也保留颜色可以用--coloralways但这样会在文本里塞满 ANSI 控制码除非你有特殊用途否则不建议。还有个排查小技巧如果ls --coloralways -F都没有任何颜色大概率是终端不支持 ANSI 序列如果ls --colorauto -F没颜色、--coloralways有颜色说明终端没问题只是 ls 判断输出目标不是终端。明白这个逻辑之后绝大多数“没颜色”问题都能快速定位。5.3 中文文件名显示乱码这个问题在把 Git\usr\bin 加入 PATH 后特别常见。cmd 默认代码页通常是 GBK代码页 936而 Git 的 ls 默认按 UTF-8 输出两边一碰撞中文文件名就变成一串乱码。最直接的解决办法是切换代码页。在 cmd 窗口里执行chcp 65001切换到 UTF-8然后再执行 ls。这种方法对当前窗口立即生效但关掉窗口就失效了而且切换代码页之后某些老的 GBK 程序可能会显示异常。更稳定的做法是给 MSYS2 环境设置LANGzh_CN.UTF-8这个用户环境变量。这样 git 的 ls 会明确按 UTF-8 输出再配合代码页切换到 65001中文显示就基本正常。挑剔一点的话还可以在 Windows 设置里打开“Beta使用 Unicode UTF-8 提供全球语言支持”但这会改变整个系统级联的默认代码页影响面比较大除非确实需要不然我不建议随便开。5.4 DLL 缺失 / 安全软件拦截 / 版本更新前面提到过单独拷贝 GNU 的 ls.exe 很容易出现 DLL 缺失问题所以要么整体用 Git for Windows 的工具链要么直接用包管理器装 lsd/eza。lsd 是 Rust 写的发布包通常用 MSVC 工具链编译对运行时 DLL 的依赖比 Cygwin 系小很多一般不会出现“找不到 cygwin1.dll”这种问题。如果 lsd 提示缺少 MSVC 运行库装一个 Visual C Redistributable 就能解决。安全软件拦截也是个现实问题。Scoop 的 shim 机制或者某些未签名的 exe会被 Windows Defender 误报。遇到这种情况先确认校验和是否和官方发布一致确认没问题后可以把对应目录加入 Defender 的排除项。升级方面包管理器用户直接scoop update lsd或winget upgrade lsdGit for Windows 用户就用它自带的更新机制保持工具在受控版本即可。6. 到底选哪个方案配置对比与我的日常组合6.1 三个方案的适用场景对比方案安装成本颜色效果功能丰富度主要副作用适合人群方案一 Git\usr\bin 的 ls需装 Git标准 Linux 配色稳定可控中依赖 GNU ls 参数usr\bin 里的 find 等工具可能与 Windows 自带的冲突刚需、不想折腾、愿意接受全家桶方案二 doskey PowerShell零安装只有 PowerShell 默认色控制弱低只能借用 Get-ChildItem每次调用启动 PowerShell延迟明显应急、禁装软件的环境方案三 lsd / eza包管理器一条命令现代彩色支持图标和 Git 状态高可深层次定制图标需要 Nerd Font配置项多喜欢折腾、讲究终端颜值和效率如果只想要稳定方案一综合成本最低。它相当于把 Linux 养成的肌肉记忆原封不动搬过来ls -l、ls -la、ls --colorauto这些参数在 cmd 里都能用。如果平常就喜欢折腾终端、注重观感方案三更值得投入。方案二我不推荐长期用但作为一个“不装任何软件”的保底手段确实也凑合。6.2 我的日常配置我自己的电脑上日常使用其实是 Windows Terminal 加 PowerShell同时把 ls 指向 lsd。真到需要纯 cmd 环境的时候AutoRun 里也会加载lslsd.exe --group-directories-first。这里分享一个可以一键完成 PATH 添加、宏文件生成、AutoRun 注册的小脚本新电脑换机后跑一遍就能恢复习惯$lsdInstalled $false $gitBin C:\Program Files\Git\usr\bin # 把 Git 的 usr\bin 加进用户 PATH if (Test-Path $gitBin) { $userPath [Environment]::GetEnvironmentVariable(Path, User) if ($userPath -notlike *$gitBin*) { [Environment]::SetEnvironmentVariable(Path, $userPath;$gitBin, User) } } # 确认 lsd 是否可用不可用则提示用 winget 安装 if (Get-Command lsd -ErrorAction SilentlyContinue) { $lsdInstalled $true } # 生成 AutoRun 批处理 $cmdrc $env:USERPROFILE\.cmdrc.bat $content echo offrn doskey lsls.exe --colorauto -Frn doskey llls.exe -l --colorautorn doskey lals.exe -la --colorautorn if ($lsdInstalled) { $content echo offrn doskey lslsd.exe --group-directories-firstrn doskey lllsd.exe -l --group-directories-firstrn doskey lalsd.exe -la --group-directories-firstrn doskey treelsd.exe --tree --group-directories-firstrn } $content | Set-Content -Path $cmdrc -Encoding ascii # 注册 AutoRun New-ItemProperty -Path HKCU:\Software\Microsoft\Command Processor -Name AutoRun -Value $cmdrc -Force | Out-Null Write-Host 配置完成新开 cmd 生效这个脚本默认写入的是 ASCII 编码正好避开批处理文件的 BOM 坑。如果你更偏好 GNU ls就保留前一条宏定义如果你装了 lsd脚本会自动把宏切成 lsd 版本。最后再分享一个实际使用中的感受给 Windows 配好顺手的ls看似是个小折腾但对日常效率的改善非常明显。以前我在 cmd 里列目录总是下意识用dir切到 Git Bash 又用ls来回切很别扭。现在所有环境统一成ls手指记忆完全一致。尤其是用 lsd 之后目录优先、Git 状态可见打开项目文件夹的瞬间心里就有数了这种体验是纯白字dir完全给不了的。如果你也想让 Windows 下的命令行稍微“顺手”一点强烈建议按本文的方案试一次。