资讯动态

告别低效:十个现代命令行工具,让Linux运维与开发更加顺手

发布时间:2026/9/13 5:55:16 来源:尧图企业网站定制
前两天在群里聊天有个刚入行的朋友问我现在 IDE 和图形化工具都做得这么顺手为什么还天天泡在黑乎乎的终端里敲命令。我当时的回答是我不是喜欢黑屏我是离不开那十个把老命令重新做了一遍的命令行工具。它们没有一个是全新的概念eza 是 lsfd 是 findripgrep 是 grep但每一个都在默认行为上做了巨大的改进——默认好看、默认顺手、默认少敲一半字符。这篇东西就是把我这两年配置里一直没删掉的那十个工具摊开讲一遍。不是罗列功能清单而是讲清楚三件事它替掉了谁、为什么值得换、实际用起来会踩哪些坑。适合天天连服务器改配置的运维、写脚本和后端的开发者、经常要在几十万行日志里捞东西的数据同学也适合刚接触 Linux、被 find 和 sed 的参数劝退过的新手。我不会假设你之前用过任何一个配置片段都能直接抄。1. 先聊聊我为什么把老命令一个个挨着换掉1.1 老一代命令行的三个真实痛点第一个痛点是默认输出对人类不友好。ls丢给你一屏一模一样的白色文件名目录和文件混在一起du -sh *在目录多的时候刷出几百行你还得自己去排序git diff只有加减号改动落在哪个函数里全靠眼睛扫。这些工具诞生在上世纪七十年代那会儿终端是电传打字机能输出字符就已经很奢侈可读性根本不是设计目标。第二个痛点是参数记忆成本高得离谱。find . -type f -name *.py -not -path */node_modules/* -exec wc -l {} \;这条命令我背了七八年每次写还要查一下-exec结尾到底是\;还是。sed -i s/old/new/g里的正则转义规则和它的捕获组语法\1更是反直觉到顶点。问题不在于难而在于这些参数我一周要用几十次每次都消耗一点注意力。第三个痛点是交互能力几乎为零。我想先看看有哪些匹配再从里面挑一个老工具的做法是先跑命令、输出一屏、眼睛扫、重新写一条更精确的命令再跑一次。这个来回在排查线上问题时格外难受因为每一步都要重新输入、重新等待。很多人说命令行效率高但效率高的前提是工具本身允许你边看边筛而不是一条命令一个坑地试。1.2 现代 CLI 工具的四个共同特征我把这十年冒出来的新一代工具总结成四个共同点理解了这四点你就能自己判断一个新工具值不值得学了。第一是默认输出即成品不需要额外加一堆--coloralways和格式化参数装完直接跑就很好看颜色、图标、对齐、单位换算全都替你做好了。第二是常见操作零参数rg 关键词就直接递归搜索整个目录不用再写-r。第三是支持交互式筛选。这一点是被 fzf 带起来的现在的工具越来越倾向于先给你一个可以缩小范围的界面而不是一次跑完给你一坨结果。第四也是最重要的一点是遵守统一的组合约定能读标准输入、能写标准输出、--help写人话、支持NO_COLOR环境变量、错误信息输出到 stderr 而不是 stdout。正是这些约定让命令行真正成为管道你可以把 rg 的结果喂给 fzf再把 fzf 的选择喂给 bat。注意不是所有新工具都遵守第四条。判断方法很简单把它接到管道里试试如果输出变了颜色或者格式乱了说明它是为终端交互设计的不适合进脚本。1.3 我的筛选标准什么才配进离不开清单我给自己定了四条硬标准。第一每天至少用一次一周用一次的再炫也不进清单。第二换成它之后我不想回去如果我只是知道有这么个东西但实际还是习惯敲ls那它就不算。第三在一台干净机器上我能用一条命令装回来需要手动编译半小时的工具我会犹豫。第四它不绑架我的工作流不需要常驻守护进程、不需要改系统级配置、卸载了不留残渣。按这四条筛下来最后留在配置里的就是下面十个。清单里没有一个是 2024 年以后才出现的爆款全是经过时间检验、社区活跃、跨平台支持良好的选手。序号替换掉的老命令现代工具我最常用的场景1lseza看目录结构和文件大小一眼扫完2findfd按扩展名、路径批量找文件3cdzoxide用关键词跳到常用项目目录4catbat读配置、看代码片段5grepripgrep全项目搜关键字秒出结果6sedsd批量正则替换不背转义7CtrlRfzf任何列表变成可模糊搜索的界面8无jq / yq处理 JSON 和 YAML 配置9dudust找出到底是谁把磁盘吃满了10topbottom看进程和资源占用的实时面板2. 文件浏览与查找ls、cd、find 的现代接棒者2.1 eza让 ls 长出颜色、图标和 Git 状态eza 是 exa 的社区延续版本安装很简单macOS 上brew install ezaDebian 和 Ubuntu 24.04 之后可以直接sudo apt install ezaArch 用pacman -S ezaFedora 用dnf install eza。如果你的发行版版本太旧装不上可以用cargo install eza从源码编译或者直接去 GitHub Release 下预编译的二进制扔到~/.local/bin。装完先别急着改别名跑几个参数感受一下。eza --icons会给每个条目加上文件类型图标eza -lh --git会在每一行右边显示这个文件在 Git 里的修改状态eza --tree --level2直接替代tree命令而且性能更好。最让我回不去的是--group-directories-first --header这个组合目录永远排在最上面而且表头会标出权限、大小、日期分别对应哪一列。# 放在 ~/.bashrc 或 ~/.zshrc 里 alias lseza --icons --group-directories-first alias lleza -lh --icons --git --group-directories-first --header alias laeza -lah --icons --group-directories-first alias lteza --tree --level2 --icons注意--icons显示乱码是字体问题不是 eza 的问题。你需要装一款 Nerd Font 并在终端设置里选中它。服务器上一般没有字体所以远程机器上我把--icons去掉只保留颜色和分组。另外一个坑是--git参数在超大仓库里会明显变慢因为它每显示一次目录就要调一次 git 状态查询几十万个文件的仓库别在根目录用。2.2 fd比 find 少敲一大半的那种爽fd 的定位非常明确把find里 90% 的日常用法变成零思考操作。对比一下就懂了找当前目录下所有 Python 文件并排除 node_modules老写法是find . -type f -name *.py -not -path */node_modules/*用 fd 就是fd -e py -E node_modules。前者我要回忆-type f的位置后者只需要记住扩展名用 -e排除用 -E。它的参数设计得很有规律-e指定扩展名-E排除路径-H包含隐藏文件-I忽略 .gitignore 和 ignore 规则-t f只找文件-t d只找目录-x对每个结果执行命令-X把所有结果一次性传给命令。这几个参数覆盖了我日常九成五的查找需求。# 找出所有日志文件并按大小排序 fd -e log -x ls -lh {} # 找出所有 Python 文件统计行数-X 批量传参比 -x 快很多 fd -e py -X wc -l # 在配置文件里找一定要加 -HI fd -HI -e conf . /etc # 对每个找到的文件单独执行命令 fd -e jpg -x convert {} {.}.webp注意fd 默认不显示隐藏文件、默认遵守 .gitignore 规则这是它的设计取向但对从 find 转过来的人是最大的坑。我第一次找/etc下的配置文件跑fd nginx什么也没找到还以为是没装。记住两组参数-H管隐藏文件-I管忽略规则找系统配置的时候无脑-HI就对了。另外-x后面那个{}是占位符{.}表示去掉扩展名的路径{/}是文件名{//}是目录部分这几个简写能省掉大量 awk 和 basename。2.3 zoxide目录跳转从记路径变成记关键词zoxide 解决的是一个特别具体的痛我在一台机器上可能有十几个项目目录散落在~/work、~/projects、/data/repos三个不同层级下面每次切过去都要敲一长串路径。zoxide 的思路是记录你访问过的目录按频次加最近使用排序你只要敲一个关键词就能跳过去。初始化只需要在配置文件里加一行bash 用eval $(zoxide init bash)zsh 用eval $(zoxide init zsh)fish 用zoxide init fish | source。用起来是这样z blog会跳到最匹配 blog 的目录z api v2支持多关键词依次匹配路径片段zi打开交互式选择界面让你从候选里挑z -回到上一个目录z ..回上级。它维护的那个数据库放在~/.local/share/zoxide/下面你可以随时用zoxide query -l看排在最前面的目录有哪些。实操心得刚装上的头两三天你会觉得它一点都不聪明因为数据库是空的。这时候千万别急着卸载老老实实用 cd 走一遍你常去的目录一般一周之后命中率就非常高了。这跟输入法词库是一个道理前期投入后期收益。另外我强烈建议不要把它初始化在脚本或非交互式 shell 里因为它会劫持 cd 的行为在 Makefile 和 CI 里跑可能出怪问题。2.4 这三个工具串起来的一套日常动线讲个具体的场景你就知道组合起来是什么感觉了。早上到工位接到一个告警说订单服务报错我先z order直接跳到项目目录zoxide然后lt看一眼目录结构确认服务在哪个子目录eza --tree接着fd -e yaml -e toml找出这个服务的所有配置文件fd最后rg timeout在配置里搜超时相关的项ripgrep。整个流程大概是十五秒而且中间没有任何一步需要我回忆完整路径。换回老工具的话第一步cd ~/work/backend/services/order-service就得敲二十多个字符还得记得住。这四步里我换了三个工具而它们彼此的配合是完全透明的因为都遵守前面说的那套标准输入输出约定。这也是我每次换新工具都会优先考虑能不能和其他工具串的原因。3. 文件内容处理cat 和 grep 的替代方案3.1 bat让 cat 带语法高亮和行号cat最大的问题是它真的只是把文件内容倒出来几万行的日志刷屏刷到你怀疑人生而且没有任何高亮。bat 本质上是cat加了个less式的分页器和语法高亮引擎打开一个 config.yaml 你能立刻看清层级结构打开一个有语法错误的 py 文件能直接看出哪一行不对劲。安装macOSbrew install batArchpacman -S batFedoradnf install bat但 Debian 和 Ubuntu 用户要注意一个坑——因为这个包名和另一个软件冲突可执行文件叫batcat而不是bat。我见过太多人在这一步卡住以为装失败了。# Ubuntu / Debian 上要这样写别名 alias catbatcat --pagingnever alias catpbatcat几个常用参数--pagingnever让输出像 cat 一样直接刷出来不分页-p等同于--styleplain只显示内容不显示行号和文件头--line-range 120:160只看指定行区间-l yaml手动指定语言有些配置文件没有扩展名时高亮会失效--diff配合 git 用能把改动的行标出来。坑点提示如果你在管道里用 bat比如bat file | grep foo不加--pagingnever会直接卡住等按键因为 bat 检测到输出不是终端但依然启用了分页器。最省事的办法是在配置里加export BAT_PAGER一劳永逸。另外我一般不把 bat 设成 cat 的别名放在脚本环境里只放在交互式 shell 的配置里原因后面讲兼容性的时候会细说。3.2 ripgrep递归搜索的事实标准ripgrep命令名rg到现在几乎是我唯一在用的搜索工具。它的默认行为解决了我过去几个最大的困扰默认递归搜子目录不用加-r默认忽略 .gitignore 里列的东西搜代码时不会被 node_modules 和 build 目录里几万个文件拖死默认跳过二进制文件和隐藏文件不会因为搜到某个二进制文件就给你吐一堆乱码。速度上它确实比 GNU grep 快但更值得说的是为什么快。一是它用了 Rust 的正则引擎并且对多文件搜索做了并行化能跑满多核二是它在遍历目录时先应用忽略规则再读文件省掉了大量无谓的 IO三是对大文件用了内存映射。实际感受是在一个几十万文件的仓库里搜关键词grep 要几秒rg 基本是瞬时出结果。# 基础搜索默认递归、默认忽略 gitignore rg func main # 只看文件名列表 rg -l TODO # 带上下文显示匹配行的前后 3 行 rg -C 3 panic: # 只搜某种类型rg 内置了类型定义 rg -t py import requests # 搜索时包含被 gitignore 的文件CI 环境里很常用 rg --no-ignore config # 只输出匹配部分配合 -r 做提取 rg -o -r $1 rid(\w) app.log它还有一个被低估的能力是配置文件。设一个环境变量export RIPGREP_CONFIG_PATH$HOME/.ripgreprc然后在这个文件里写你每次都要加的参数比如--smart-case有小写就忽略大小写、有大写就精确匹配比单纯加-i聪明、--hidden、--glob!.git/。这样你敲的每一条 rg 都自带这些优化。注意事项ripgrep 默认用的是 Rust regex 引擎它为了保证线性时间性能故意不支持反向引用和环视这类高级语法。如果你的正则里用了(?...)或者\1会报错。解决办法是加-P参数切到 PCRE2 引擎但要注意这时候性能会下降而且 PCRE2 需要编译时支持某些预编译包没开这个选项。3.3 sd正则替换不用再背反斜杠sed是我最想换掉但又最难换掉的一个因为它在脚本里无处不在。但交互式地做批量替换时sd 的体验好太多了。看一个对比把所有文件里的localhost:8080换成api.internal:8080sed 写法是sed -i s/localhost:8080/api.internal:8080/g *.yamlsd 写法是sd localhost:8080 api.internal:8080 *.yaml。少了一个s/.../.../的外壳也少了那个让人紧张的-i。捕获组的差异更明显。sed 用\1\2sd 用$1${2}而且支持命名捕获。举个实际例子把日志里的ts1712345678 levelerror重排成error 1712345678sed 里我要写sed -E s/ts([0-9]) level(\w)/\2 \1/sd 里是sd ts(\d) level(\w) $2 $1可读性立刻上去了。几个关键参数-p预览模式只打印替换结果不写文件我强烈建议所有批量替换先用-p跑一遍-s字面量模式不进正则引擎搜带特殊符号的字符串时特别有用-f指定文件列表。这是一个必须记住的差异sd 默认就是全局替换等价于 sed 的g标志你不需要也不应该再加g。我第一次用的时候习惯性写成sd foo bar g结果发现它把文件里所有的字母 g 单独替换掉了。这个坑踩过一次就忘不了。另外 sd 的-i参数在它的语义里是就地修改跟 sed 一样但因为它默认就是全文件替换用之前一定先-p看一眼。3.4 三者组合的实战在海量日志里定位一次报错说个真事。上周排查一个线上问题手上有个 2.3GB 的应用日志需要找出所有返回 500 的请求把它们的时间戳和请求 ID 提取出来看看有没有规律。用老的grep加awk组合光跑一遍就要几十秒用 rg 加 sd 加 bat 的组合整个过程不到一分钟。第一步先用 rg 摸清规模rg -c status500 app.log先知道大概有多少条几十条还是几万条决定了后面策略完全不同。第二步提取关键字段rg -o -r $1 $2 ts(\S) .*?status500.*?rid(\S) app.log | head -50这里-o只输出匹配部分-r做捕获组重排输出就很干净。第三步统计规律把上一步的结果接| awk {print substr($1,1,13)} | sort | uniq -c | sort -rn按小时聚合看是不是集中在某个时间窗口。最后一步是看上下文。假设上一步发现请求 ID 是a3f9c2e1我要看它前后发生了什么用 bat 直接定位rg -n a3f9c2e1 app.log拿到行号是 12847392然后batcat --line-range 12847380:12847420 app.log精准看这四十行。整个排查过程的核心思路是先用 rg 缩小范围再用 bat 精读这个组合比翻文件快一个数量级。4. 交互、结构化数据与系统观测4.1 fzf把任何列表变成可模糊搜索的交互界面fzf 是这份清单里最难用一句话解释清楚的工具因为它的定位是通用模糊筛选器。它读标准输入在终端里给你一个可以用方向键和模糊输入筛选的界面选中的结果写到标准输出。就这一个能力配上各种命令之后能变出几十种用法。安装完第一件事是启用快捷键绑定。bash 用户在新版里可以eval $(fzf --bash)旧版需要 source 那个 examples 目录下的 key-bindings 脚本。启用之后你会得到三个神仙快捷键CtrlR模糊搜索历史命令比默认的反向搜索好用十倍因为它支持模糊匹配你只记得命令里包含docker log这几个字就能翻出来CtrlT在当前命令行里插入一个选中的文件路径AltC变成一个可以模糊搜索的 cd。# 用 fzf 选文件再打开 vim $(fzf) # 带预览的选文件右边实时显示文件内容 fd -t f | fzf --preview batcat --coloralways --stylenumbers {} --height 60% # 从进程列表里挑一个杀掉 ps -ef | fzf | awk {print $2} | xargs -r kill -9 # 切换 git 分支 git checkout $(git branch --format%(refname:short) | fzf) # 搜索并跳转到历史命令里的某个参数位置 history | fzf --tac | sed s/^ *[0-9]* *//要让 fzf 真正好用必须改两个环境变量。export FZF_DEFAULT_COMMANDfd -t f -H把默认的查找命令从 find 换成 fd速度差距在几十万文件的仓库里非常明显。export FZF_DEFAULT_OPTS--height 40% --layoutreverse --border --infoinline把界面变成底部弹窗式而不是全屏这样不打断你的上下文。4.2 jq 与 yq结构化数据的命令行手术刀到 2025 年了配置文件大部分不是 JSON 就是 YAML用 grep 去处理这两种格式基本等于自虐因为一个字段可能跨好几行、缩进一变规则就失效。jq 处理 JSONyq 处理 YAML它们本质上是把结构化数据变成可以精确寻址的对象。jq 的基本功jq .格式化输出jq .items[].name取出数组里每个元素的 namejq .[] | select(.age 30)条件筛选jq -r去掉字符串外面的引号不加这个参数拿到的结果会带引号直接喂给下一步命令会出错jq -s把多个 JSON 合并成一个数组处理。实际用得最多的场景是读接口返回和查配置文件# 从接口返回里提取所有实例的 IP curl -s http://internal-api/instances | jq -r .data[].ip # 找出所有副本数大于 3 的服务 kubectl get deploy -o json | jq -r .items[] | select(.spec.replicas 3) | .metadata.name # 把嵌套 JSON 拍平成一行行 jq -r to_entries[] | \(.key)\(.value) config.jsonyq 处理 YAML 更贴近我们的日常尤其是批量改配置。yq .spec.containers[].image deploy.yaml可以一次把所有容器的镜像列出来加上-i直接原地修改文件yq -i .spec.template.spec.containers[].image registry.internal/app:v2.3.1 *.yaml一条命令改一批文件的镜像版本比手改或者写 sed 靠谱得多。这是一个团队协作里真实踩过的坑yq 有两个主流实现一个是 Python 写的pip install yq底层其实是把 YAML 转成 JSON 再调 jq另一个是 Go 写的mikefarah/yq。两者的命令行语法有差异比如 Python 版更强调 jq 表达式Go 版有很多自己的子命令。我们组里两个人照着同一份文档操作结果一个成功一个报错排查半天才发现装的不是同一个东西。装完先跑yq --version看清楚是哪个版本团队里统一一下。4.3 dust 与 bottom磁盘和进程的现代观测面板磁盘满了这件事用du -sh *排查过的人都懂那种痛苦输出一屏目录名加数字没有排序、没有百分比、没有可视化你还得自己sort -h再看。dust 把这些全做了它默认就按大小排序用条形图直观显示每个目录占总量的比例还会自动递归到合适的深度。常用参数dust -d 2 /var限制只显示两层深度避免输出太长dust -n 20只显示前 20 项dust -r /var反向排序有时候反而能发现小文件扎堆的问题dust -s只显示总大小不展开。实际排查磁盘告警的动线是dust -d 2 /看哪个顶层目录异常然后一路-d往下降通常三层之内就能定位到罪魁祸首。bottom命令名btm是 top 和 htop 的现代替代界面信息密度高很多而且支持鼠标操作。核心快捷键t切换树状进程视图能看清父子关系排查 fork 爆炸时特别有用dd杀掉选中进程先按一次 d 进入删除模式再确认避免误杀e展开某个进程的详细信息/搜索进程名方向键和鼠标滚轮直接滚动。它还带网络、温度、磁盘的实时图表一台机器上想看什么基本都有。注意在容器里跑 bottom 经常显示不全因为容器默认限制了 /proc 的可见范围你看不到宿主机上的其他进程CPU 和内存数据也可能是宿主机视角而不是容器的。这时候改用docker stats或者专门给容器用的监控方案更准确。另外--battery参数在某些虚拟机上要额外权限报错的话去掉这个参数就行。4.4 delta让 git diff 真正能读这个严格来说是我清单里的第十一个标题写着十个我得诚实但 delta 我实在舍不得删就当彩蛋放在这。它做的事情是把git diff的输出渲染成带语法高亮、行号、左右分栏的对比视图。原来一段 Python 代码改动你只能看到加减号现在函数名、缩进层级、改动块的位置一目了然代码审查效率直接翻倍。配置就写在~/.gitconfig里一次配好终身受用[core] pager delta [interactive] diffFilter delta --color-only [delta] navigate true line-numbers true side-by-side true syntax-theme Monokai Extended [merge] conflictstyle diff3 [diff] colorMoved defaultnavigate true是个隐藏神技配好之后在 diff 视图里可以用n和N在改动块之间跳转代码审查时不用滚轮滚半天。side-by-side左右分栏在宽屏终端上非常爽但终端宽度小于 100 列的时候会挤成一团我现在是写了个判断终端宽度的小函数动态切换。5. 装好只是开始配置、别名与 GUI 的边界5.1 包管理器选型与跨平台安装同一个工具在不同系统上的安装方式差异挺大而且坑主要出在 Debian 系。macOS 用 Homebrew版本总是最新的几乎不会有问题。Arch 用 pacman滚动更新所以版本也很新。Fedora 用 dnf基本够用。真正需要留意的是 Debian 和 Ubuntu因为包名冲突和版本滞后两个问题都存在。系统包管理器典型坑点macOSHomebrew基本无坑版本最新Arch / Manjaropacman基本无坑Fedora / RHELdnf部分工具要加 copr 源Ubuntu / Debianaptbat 装完叫 batcatfd 装完叫 fdfind通用兜底cargo / 预编译包放进 ~/.local/bin 并确保在 PATH 里Ubuntu 上那个改名问题的原因很简单bat和fd这两个短名字在 Debian 仓库里已经被别的老软件占用了所以新工具只能用batcat和fdfind这两个名字。解决办法是加别名或者在~/.local/bin里做个软链接ln -s $(which batcat) ~/.local/bin/bat。我选后者因为这样脚本里也能用bat这个名字。还有一个版本滞后的现实问题。apt 仓库里的工具版本通常落后上游一到两年比如某个 fd 的新参数在老版本里压根没有。碰到这种情况我一般走 cargocargo install fd-find编译出来的二进制直接扔在~/.cargo/bin版本是最新的。用 cargo 装的前提是你机器上有 Rust 工具链只是偶尔装一两个工具的话去 GitHub Release 页面下预编译二进制更省事解压放到~/.local/bin加个执行权限就能用。5.2 别名、函数与配置文件的组织方式我在.bashrc里堆过两千行配置最后的结果是每次改东西都像在雷区里走。现在的做法是把配置按主题拆成多个文件放在~/.config/shell/下面主配置里用循环 source 进来。# ~/.bashrc 里只留这一小段 if [[ $- *i* ]]; then for f in $HOME/.config/shell/*.sh; do [[ -r $f ]] source $f done fi那个[[ $- *i* ]]的判断很关键它的意思是只在交互式 shell 里加载这些别名和函数。因为大量别名会破坏脚本行为比如你把ls设成eza之后某个脚本里写ls | awk {print $9}就会因为输出格式变了而拿到错误的列。用这个判断把别名圈在交互式 shell 里脚本照旧用原生命令两边都安全。简单的东西用别名就够了稍微复杂一点的用函数。比如我不喜欢每次rg都手动加排除目录就写了个函数# ~/.config/shell/search.sh rgs() { rg --hidden --glob !.git --glob !node_modules --glob !dist $ } # 找到文件后直接看内容 look() { local f f$(fd -HI -t f $1 | fzf --preview batcat --coloralways {}) [[ -n $f ]] batcat --pagingnever $f }5.3 远程机器上怎么快速铺开我经常要登到临时机器上排查问题那些机器上什么都没有这时候就需要一套快速铺开的办法。我准备了一个 bootstrap 脚本先检测发行版然后分别走 apt 或 dnf 装基础包接着把预编译二进制拷到~/bin最后 source 一份精简的配置。整个脚本不到五十行跑完大概两分钟。有几个经验值得分享。第一不要把整套 dotfiles 推上去尤其是别去改别人的~/.bashrc很容易覆盖掉别人的配置而且是不可逆的。我现在的做法是全部塞进一个独立目录~/.local/cli-kit/然后让用户自己决定要不要 source。第二没有 root 权限时别硬装预编译二进制是你唯一的选择下到~/bin再export PATH$HOME/bin:$PATH就行注意放在 PATH 前面避免和系统里的老版本冲突。第三远程机器的终端环境要提前确认。有些机器TERM变量是dumb或者没设置颜色和图标全废跑出来的东西比原生命令还难看。我的脚本里会检测一下TERM如果是 dumb 就自动关掉所有花哨参数。第四注意 .gitignore 规则的影响。有些生产环境的仓库里配了很激进的忽略规则rg和fd默认会跳过那些文件导致你以为文件不存在。这种情况在排查问题时很危险脚本里我给rg加了--no-ignore的快捷别名。5.4 哪些事交给图形化文件管理器更省事说到这我想聊个有点反直觉的观点不是所有事都该在命令行做。这些年桌面环境的文件管理器比如深度桌面环境里的 dde-file-manager、GNOME 的 Nautilus、KDE 的 Dolphin在权限管理这块做得其实很方便右键属性里勾选权限的界面比敲chmod 755直观太多了。尤其是不常写八进制权限数字的人rwxr-xr-x和644之间换算经常要停下来想一下。在图形界面里你可以一次框选几十个目录右键属性里统一勾上所有者可读写执行、组可读可执行、其他可读可执行一次操作搞定一批。而命令行里要写fd -t d -x chmod 755 {}写错一个数字就是权限事故。还有一个典型场景是管理远程文件权限。桌面文件管理器一般内置了连接远程服务器的能力FTP、SFTP 这类连上之后整个目录树是可视化的你想知道某个文件为什么访问不了点开属性看权限列一眼就能发现是不是少了执行位。相比之下在终端里ls -l看一屏权限字符然后stat一个个查效率差不少。场景推荐方式理由批量统一几个目录的权限图形化文件管理器一次框选右键搞定不怕数字写错查看远程目录的权限异常图形化 终端辅助图形看权限列终端里 fd 定位文件权限规则要写进部署脚本命令行 chmod可复现、可版本管理、有审计记录跨几十台机器统一权限命令行 配置管理工具图形界面无法批量化临时给同事开个目录权限图形化操作快不涉及脚本化需求我的实际分工是这样的探索和调试阶段用图形界面因为反馈直观、试错成本低固化和批处理阶段回到命令行因为要可复现、要能进版本库、要能跨机器跑。这两者不是对立的最舒服的状态是终端里用 fd 和 rg 负责找文件管理器负责改各干各擅长的事。6. 踩坑记录与问题速查6.1 颜色、字体与终端渲染问题这类问题的表现高度一致图标变成方块或者问号颜色要么全没了要么刺眼得不行。原因基本就三个。第一是字体没装 Nerd Fonteza 的--icons、fzf 的部分符号、bottom 的图表都会受影响。解决办法是去下任意一款 Nerd Font 并在终端设置里选中它注意改的是终端的字体设置不是系统字体。第二个原因是TERM变量设置不对。很多人在服务器上的TERM是xterm某些工具就只给你 8 色。可以试试export TERMxterm-256color现代终端一般支持 256 色甚至 truecolor。如果想彻底解决检查一下COLORTERM变量是不是truecolor不是的话设一下。第三个原因是某些工具的颜色选择和你的终端主题冲突比如浅色背景配白色高亮文字。这种时候可以用NO_COLOR1环境变量全局关掉颜色或者单独调某个工具的配色主题。一个隐蔽的坑bat 在管道里不加--pagingnever会卡住这个前面提过。但还有个更隐蔽的版本——某些工具检测到 stdout 不是终端时会自动关掉颜色结果你rg --coloralways强制开颜色喂给下一个工具下一个工具输出就乱了。判断原则很简单给终端看的输出带颜色给管道看的输出不带颜色别强行覆盖。6.2 与老脚本、老管道的兼容冲突这是替换命令时最需要警惕的一类问题因为它不会立刻报错而是悄悄给你错误结果。最常见的是别名污染脚本。你把ls设成eza之后脚本里任何ls -l | awk {print $5}取文件大小的写法都可能失效因为 eza 的默认列顺序和 ls 不一样。解决办法有三个层次。最稳的是脚本里用绝对路径或者command前缀写command ls就会绕过别名。其次是在脚本开头unset掉可能有影响的别名。最后也是我推荐的用前面讲的[[ $- *i* ]]把别名限制在交互式 shell 里从源头上避免脚本看到别名。第二类冲突是默认行为的差异。rg 和 fd 默认忽略 .gitignore这个设计在大部分时候是优点但在 CI 里可能让构建脚本找不到文件。我在一个项目里遇到过打包脚本用rg -l version找版本文件本地跑没问题CI 上因为 .gitignore 恰好把那个生成目录排除了直接找不到文件。排查了半天才想到加--no-ignore。记住这个原则交互式探索用默认行为脚本里一律显式声明你要什么。6.3 性能与资源占用的误解很多人以为新版工具用 Rust 写的所以一定快这个结论只在一部分场景成立。rg 快是真的但它快在并行和提前过滤而不是单纯的语言优势。如果你的搜索范围在单个超大文件里rg 和 grep 的差距其实没有想象中那么大。同理 fd 在本地磁盘上比 find 快但在 NFS 或者网络挂载的目录上它的并行遍历反而可能更慢因为网络延迟放大了并发查询的开销。在网络盘上记得用fd -j1限制并发数。第二类误解是新工具占内存。实际上 rg、fd 这类工具的内存占用和 grep、find 是一个量级的真正占资源的是 eza 的--git参数每个目录都要调一次 git和 bottom 的实时采样默认每秒刷新一次可以调成更低频率。eza --git 在几十万文件的仓库根目录跑能让你明显感觉到等待这时候要么缩小范围要么干脆去掉这个参数。第三类误解发生在容器里。bottom 在容器中显示的 CPU、内存数据经常不准因为 /proc 看到的是宿主机视角或者被 cgroup 限制过这不是 bottom 的 bug是容器隔离机制决定的。容器里的资源观测应该用容器平台自己的工具别指望 top 系的工具能看出真相。6.4 一张速查表收尾把最常用的组合整理成一张表贴在你自己的备忘录里前两周对着用之后基本就刻进肌肉记忆了。我想干什么用什么命令看目录目录排前面带图标ls已别名到 eza看目录树两层lteza --tree --level2找某类型文件排除干扰目录fd -e py -E node_modules在系统目录里找配置fd -HI -e conf . /etc跳到某个项目目录z 项目关键词全项目搜关键词rg 关键词搜被 gitignore 的文件rg --no-ignore 关键词提取匹配部分rg -o -r $1 pattern file读某个文件的某段batcat --line-range 100:140 file批量正则替换先预览sd -p old new *.yaml选一个文件再操作vim $(fzf)从进程里挑一个杀ps -ef | fzf | awk {print $2} | xargs -r kill看 JSON 字段jq -r .data[].name resp.json批量改 YAMLyq -i .spec.x v2 *.yaml找磁盘占用大头dust -d 2 /var看实时进程面板btm这十个工具我差不多花了两年时间才把清单固定下来中间换掉过几个一开始用 exa后来因为项目停止维护换成了 ezagrep 和 rg 并存过很长一段时间直到某次在一个大仓库里被 grep 卡了三秒才彻底倒向 rg。现在再看这台机器的配置别名、函数、环境变量加起来也就两百行但它们每天帮我省下的时间很难量化。你要是只打算试一个我建议从 fd 开始因为它替换掉的 find 语法最反人类收益最直观要是想一次装齐就把上面这张表里的命令挑几个写进你的 shell 配置先跑一周看看哪个用得上、哪个用不上用不上的删掉就行配置文件里留着不用的别名反而是负担。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价