RH134这门课网上能搜到一大堆资料但真正把它讲透的笔记不算多。第1章标题是“提高命令行运行效率”乍一看像是废话——都混到进阶课了谁还不会敲命令可实际一到生产环境或者考场差距立马就出来了有人一条命令搞定批量操作你要写五条还得逐个确认三遍有人十几秒就把日志里需要的信息提取完你还在CtrlC、CtrlV之间反复横跳。这一章的核心不是教你几条新命令而是把 shell 的底层能力系统性地串起来配置加载机制、补全、历史命令扩展、别名、通配符、花括号展开、命令替换、vim 基础编辑。每一个单项拆开都不难难的是你要真正理解它们为什么这么设计然后组合起来用。这篇文章我把整章的知识点按实际操作的维度重新组织一遍既包括考点也包括我用了这么多年终端踩过的坑和练出来的习惯。1. 内容整体设计与思路拆解1.1 这不是背命令是拆解“终端里的时间都去哪了”很多人觉得命令行效率等于“记的命令多”所以学习时拼命背参数。但 RH134 第1章的思路完全不同它先让你承认一件事情——你在终端里的大部分时间其实消耗在重复劳动上。比如你在 /var/log 下面查日志一遍遍输入 cd /var/log然后 ls然后 less最后发现路径敲错了又要重来。又比如你每天要重启某个服务每次都完整敲一遍 systemctl restart xxx.service。这些操作本身没有智力含量纯粹是机械重复。命令行效率高的人不是记性更好而是把“机械重复”这件事件外包给了 shell 的机制补全帮你少敲字母历史命令帮你少敲整行别名把长命令压缩成一个词通配符和花括号展开把批量操作浓缩成一次输入。所以这一章真正的问题不是“你知道多少命令”而是“你知不知道 shell 有这些减少重复的机制以及如何在几分钟内把它们调用出来”。我在带新人的时候有个观察很多刚从图形界面转过来的人在终端里最大的痛不是不会写命令而是不敢分解任务。他们习惯一次只做一件事完成之后再想下一件。而熟练的运维是把一个任务拆成“文件操作 文本处理 服务控制”几个环节然后用 shell 的机制把每个环节的击键量压到最小。第1章就是在帮你建立这种分解思维。1.2 课程开篇的真正用意把碎片技能连成技能链RH134 整个课程是围绕“系统管理进阶”展开的第1章之所以安排命令行效率是因为后续的章节——比如文件系统管理、日志分析、系统调优——全部要高频使用终端。如果命令行基本功不扎实后面学再多模块实操时都会被“敲命令太慢”拖后腿。这一章的知识点表面上零零散散shell 类型、历史命令、alias、通配符、vim……但你往深了看它们是一条技能链上的扣子。比如你要批量修改一堆配置文件的备份你需要用到通配符定位文件cp /etc/xxx*.conf /backup/花括号展开生成文件名{1..10}Tab 补全减少路径输入vim 打开其中一个文件检查内容这四个技能单独看都是小点连起来就是一次高效的文件备份操作。这就是第1章的开篇思路先练基本功再谈上层模块。它不是要你背参数表而是让你形成一套“先想清楚要做什么再选择最小击键路径”的操作习惯。2. 核心细节解析与实操要点2.1 shell 类型与配置加载改了不生效的根源先说 shell 类型。Linux 默认的交互 shell 是 bash绝大多数系统管家的日常工作也是跟 bash 打交道。你可以用 echo $SHELL 查看自己的登录 shell用 cat /etc/shells 查看系统支持哪些 shell。虽然 zsh、fish 近年来热度很高但 RH134 围绕 bash 展开理由很实在bash 是所有 Linux 发行版默认自带的脚本兼容性最好生产环境里你没法保证每台机器都装了 zsh。真正容易踩坑的是配置文件的加载顺序。bash 启动时会区分“登录 shell”和“非登录 shell”登录 shell通过 ssh 登录、或者用 su - 切换会读取 /etc/profile、~/.bash_profile非登录 shell打开一个终端窗口、或者在已有 shell 里执行 bash会读取 ~/.bashrc也就是说你在 ~/.bashrc 里加了一个 alias然后重新用 ssh 登录理论上 .bash_profile 里面如果写明 source ~/.bashrc它才会被加载如果没写这个 alias 可能就不生效。解决这个问题倒不难编辑完配置文件之后用 source ~/.bashrc 重新加载一次或者干脆重新登录会话。但你要明白原理不然以后排查“为什么我的 alias 时灵时不灵”会非常痛苦。实际操作时我建议这样配置把自定义的 alias、函数、快捷键设置全部写在 ~/.bashrc 里然后在 ~/.bash_profile 里保留 source ~/.bashrc 这一行。这样无论登录方式怎么切换你的习惯配置都能带过来。2.2 Tab 补全补全命令、路径、变量的一石三鸟Tab 补全是命令行效率里性价比最高的一项技能但也是最容易被忽视的。很多初学者觉得 Tab 就是补全文件名其实 bash 的补全范围远不止这个命令补全输入 sys连按两次 Tab会列出所有以 sys 开头的命令路径补全输入 /etTab 补全成 /etc/变量补全输入 $HOTab 补全成 $HOME用户名补全输入 ~roTab 补全成 ~root/主机名补全输入 ssh 用户host 时对主机名也能补全我在实际工作中最常用的补全场景反而是 systemctl。比如我想执行 systemctl restart sshd只需要敲 systemctl restart ssh然后 Tabbash 会补全成 sshd.service。这个操作每天能省几十次击键。尤其在远程服务器上编辑配置少敲一个字母就意味着少一次出错的可能。如果连续按两次 Tab 没有反应大概率是系统少装了 bash-completion 包。在多数发行版上安装这个包之后补全会进入“菜单选择模式”显示候选项继续按 Tab 可以在候选项里循环切换按 Enter 选中。这个体验非常接近现代 IDE 的补全。还有个小技巧如果你发现自己频繁输入同一个长路径前缀可以在 ~/.bashrc 里设置 INPUTRC或者给目录设置 CDPATH。对于 RH134 考试层面熟悉基本补全和了解 bash-completion 的增强能力就够了。2.3 历史命令扩展从按方向键升级到“感叹号”历史命令可能是第1章里“技巧感”最强的内容。bash 会记录你敲过的每条命令用 history 可以查看。方向键上下翻是大家都知道的操作但 RH134 要考的是 shell 历史展开也就是用感叹号快速复用之前的命令。举几个最实用的!! 执行上一条命令!$ 引用上一条命令的最后一个参数!* 引用上一条命令的所有参数!n 执行历史记录里编号为 n 的那条命令编号用 history 查看!string 执行最近以 string 开头的命令CtrlR 进入反向搜索输关键字多次按 CtrlR 往前翻匹配结果举个实际例子。你刚执行过 mv /tmp/install.log /var/log/app.log然后想进入 /var/log 目录看看文件这时候直接敲 cd !$bash 会把 !$ 替换成 /var/log/app.log执行的就是 cd /var/log/app.log。如果你本意是切到 parent 目录执行 cd !$ 之后还要再 cd ..那么更聪明的做法是在 mv 时就把目标目录作为最后一个参数比如 mv /tmp/install.log /var/log/然后 cd !$ 就是 cd /var/log/。这里有几个容易出错的细节。!$ 替换的是“上一条命令”最后一个参数如果你上一条命令是 echo hello那么 !$ 就是 hello而不是你脑子里的某个文件名。另外历史展开一旦用错可能在根目录执行了 rm -rf 这类操作所以我建议你在交互实验的时候先用 echo 验证展开结果比如敲 echo !!先用回显看看 bash 要执行的内容是什么再真正运行。这个习惯在考试时也能救你一命——考场上打错一条命令的代价比平时高得多。为了避免敏感信息进入历史记录可以在 ~/.bashrc 里设置 HISTCONTROLignorespace这样以空格开头的命令不会被记录。比如你输入“ mysql -u root -pSensitivePassword”前面加一个空格这条命令就不会进 history。这算是运维里的基本自我保护意识。2.4 重定向思维效率的前提是不出错严格来说重定向不属于“提高输入速度”的技巧但它决定了你命令行的输出能不能正确送到该去的地方所以这一章也会涉及。重定向的核心就几个符号标准输出重定向覆盖写标准输出重定向追加2 标准错误重定向21 把标准错误合并到标准输出 把标准输出和标准错误都重定向到同一文件 标准输入重定向| 管道把前一个命令的输出作为后一个命令的输入实际操作中最常见的坑是只重定向了标准输出没管标准错误。比如你写一个检查脚本 command result.log结果命令报错你打开 result.log 发现是空的会误以为“没有错误”。正确做法是 command result.log 21把报错信息也写进日志排查问题时才知道到底发生了什么。管道的思维可以这样理解把每个命令当成一个“加工工位”前一个工位处理的产物直接送到下一个工位。比如查询某个进程并杀掉ps aux | grep java | grep -v grep | awk {print $2} | xargs kill -9。这一串看起来复杂但拆开看就是四个工位依次处理。3. 实操过程与核心环节实现3.1 把光标移动练成手指记忆命令行里有一个很反直觉的事实很多人觉得“我打错的字符不多”实际上恰恰相反。你在写一条长命令时光标要从末尾回到前面改一个参数有些人会按 15 次左方向键有些人按一次 CtrlA 就到行首。区别不在于智力而在于快捷键习惯。bash 默认支持 emacs 风格的键绑定常用的有几组CtrlA 跳到行首CtrlE 跳到行尾CtrlU 删除光标位置到行首的字符CtrlK 删除光标位置到行尾的字符CtrlW 删除光标前一个词CtrlY 粘贴刚才删除的内容CtrlL 清屏AltB / AltF 向前/向后跳一个词训练方法我建议用“整行操作法”故意输入一条很长的命令然后用 CtrlA 回行首、CtrlU 删掉、CtrlY 恢复再 CtrlE 跳到行尾整个过程尽量不碰方向键。每天练上十几遍一周左右就能形成手指记忆。这种训练不用专门找时间你在正常干活的时候有意识地强制自己别用方向键就行。我在实际排查故障时用的最多的是 CtrlU 和 CtrlY 的组合。比如我输入了一长串命令发现前面的参数错了不用一个一个删直接 CtrlU 删干净或暂时“剪切”改好后如果还要用原来的后半段CtrlY 还能粘回来。这个组合在反复调整一条复杂命令时特别高效。3.2 alias 别名高频命令的快捷键alias 是把长命令映射成短单词的机制语法很简单alias 名字要展开的命令。比如alias llls -l --colorauto alias grepgrep --colorauto alias rmrm -i alias cpcp -i alias mvmv -iRed Hat 系默认会配置一些别名尤其是 rm/cp/mv 带交互确认这是防止误删的重要保护。生产环境中我强烈建议保留这些即使你觉得每次删除都要输入 y 很烦也比误删重要文件重建系统强一万倍。alias 有几个点值得注意。第一alias 只在交互式 shell 生效脚本里默认不加载所以在脚本里依赖 alias 往往是不可靠的。第二如果你临时想绕过某个 alias直接在命令前面加反斜杠比如 \rm 会执行原本的 rm 而不是 rm -i 的别名。第三alias 不能自己递归比如 alias lsls -labash 在展开别名时不会无限套娃而是调用原始的 ls 命令这个设计避免了死循环。设置别名后要 source ~/.bashrc 才能在当前会话生效。检查别名是否生效用 type aliasName如果输出“aliasName is aliased to ...”就说明生效了。考试中常考的是如何在非交互 shell 里使用 alias答案是使用 bash 的 expand_aliases 选项或者直接在命令行先 shopt -s expand_aliases。这个考点比较冷但确实出现过。3.3 通配符与花括号展开批量处理的组合拳通配符是 shell 自带的文件名匹配能力和正则表达式要区分开。通配符只作用于文件名而且通常是路径中的文件名部分。常用符号匹配任意长度的任意字符? 匹配单个任意字符[abc] 匹配方括号中的任意一个字符[a-z] 匹配一个范围[!0-9] 匹配非数字的单个字符比如 ls *.txt 列出所有以 .txt 结尾的文件ls file?.log 匹配 file1.log、fileA.log但不匹配 file10.log。cp /data/config-[ab].conf /backup/ 只复制 config-a.conf 和 config-b.conf 两个文件。花括号展开则更早于文件名匹配它直接生成一个字符串序列不管目标文件是否存在。比如 echo {1..5} 输出 1 2 3 4 5echo {a,b,c}.txt 输出 a.txt b.txt c.txt。花括号展开最大的价值是批量创建文件或目录mkdir -p /data/{logs,tmp,backup}/{2023,2024} 一条命令就能建出 logs/2023、logs/2024、tmp/2023、tmp/2024、backup/2023、backup/2024 六个目录。如果用传统方式你得敲六条 mkdir -p 命令。这里有一个极容易踩的坑通配符在没有匹配到文件时bash 默认把通配符本身作为字面量传下去。比如你在空目录里执行 ls *.txtbash 不是返回“没有匹配文件”而是把 *.txt 作为参数传给 lsls 报错说没有这个文件。我在写脚本时经常因为这个导致逻辑错误所以建议在脚本里先使用 nullglob 选项shopt -s nullglob没有匹配时展开为空字符串而不是字面量。这属于进阶一点的知识但理解了它你在排查“为什么 ls 会看到一个不存在的文件名”这类问题时就不会发懵。3.4 命令替换与变量命令里的自动化命令替换的作用是获取一个命令的输出把它塞进当前命令的某个位置。语法有两种旧式反引号command和新式 $(command)。RH134 和现在的主流实践都推荐 $(command)原因很简单反引号里嵌套反引号要转义$(command) 天然支持嵌套而且更容易阅读。实用场景很多。比如备份文件加时间戳tar -czf /backup/www-$(date %F).tar.gz /var/www/html。date %F 输出 2024-11-15最终生成的文件名就是 www-2024-11-15.tar.gz。再比如批量日志归档mv /var/log/app/$(hostname)-*.log /backup/。命令替换还有一个要注意的点在双引号中$() 依然会被执行。所以 echo $(date) 会输出当前时间字符串而 echo $(date) 因为单引号只会输出字面量 $(date)。变量展开也是同一套逻辑先做参数展开、命令替换再做分词和文件名扩展。理解这个先后顺序你就知道为什么双引号内 $ 要展开单引号内 $ 不展开。3.5 vim 基本功编辑配置文件不过夜RH134 对编辑器要求是掌握 vim 的基础编辑。学习 vim 最大的障碍不是记不住命令而是不知道“现在处于哪个模式”。vim 有四种模式但入门先掌握三种Normal 模式vim 启动后的默认模式所有按键都是编辑命令不是往文件里输入字符Insert 模式按 i 进入此时按键就是在光标处输入文本按 Esc 回到 Normal 模式Command-line 模式在 Normal 模式按 : 进入用于执行保存、退出、搜索、替换等命令在 Normal 模式下hjkl 四个方向键对应左、下、上、右。很多新手受不了 hjkl但一旦你手指习惯了你会发现双手不需要离开主键区光标移动的击键路径极短。常用的编辑操作我整理一下gg 跳到文件首行G 跳到文件末行w 跳到下一个单词开头dd 删除当前行dw 删除当前单词u 撤销yy 复制当前行p 粘贴到光标下方/word 向下搜索 word按 n 跳到下一个匹配:%s/old/new/g 全文替换:wq 保存退出:q! 不保存强制退出ZZ 保存退出考试里最常考的是“在 vim 中做全局替换”。比如把配置里的 8080 改成 8081输入 :%s/8080/8081/g然后 :wq。实操中我还会用 vimdiff 比较两个配置文件vimdiff file1.conf file2.conf差异行会高亮显示这在排查配置不一致时非常直观。vim 最让人崩溃的场景是异常退出后留下 swap 文件。当你再次打开同一个文件时vim 会提示该文件被锁并想做一个恢复。如果你确定不需要恢复直接找到同目录下的 .文件名.swp把它删掉即可如果有未保存的修改则按提示执行 :recover 恢复。这个问题的根源是 vim 为了防止多人篡改同一文件而设计的锁机制理解了“为什么”你就不会再对着报错愣神。4. 常见问题与排查技巧实录4.1 Tab 补全失效现象是敲了一部分命令按两次 Tab 一点反应都没有。最普遍的原因是系统没装 bash-completion 包。早期的 bash 只支持命令名和文件名的补全很多复杂命令的参数补全比如 systemctl、dnf 的子命令是额外提供的。排查思路分三步第一确认当前 shell 是不是 bash第二确认 bash-completion 包是否安装第三检查 /etc/profile.d/ 下的 bash_completion.sh 是否被加载。有时候你安装了包但当前会话没有执行 source /etc/profile需要重新登录一次。还有个冷门原因如果你在 .bashrc 里自定义了 complete 设置比如 complete -o default -o bashdefault xxx这个设置可能会覆盖默认补全行为。我一度自定义了 git 子命令补全结果把其他命令的补全搞坏了后来干脆把自定义 complete 全部清理掉用现成的 bash-completion。4.2 历史命令“丢了”或者只有一部分历史记录存储涉及两个变量HISTSIZE 控制当前会话内存里保存多少条历史HISTFILESIZE 控制历史文件里保存多少条。默认值因发行版而异但如果你把 HISTSIZE 设置得太小历史文件的内容会频繁被截断。此外如果多终端并发操作每个终端在退出时都会把历史写回文件后退出终端的写入会覆盖先退出终端的历史。这是 bash 早期的一个老问题。解决办法是在 ~/.bashrc 里设置 shopt -s histappend让所有终端的历史记录追加写入而不是覆盖。考试里很少考 histappend但实际运维中这个设置很重要。我在一台长期运行的服务器上吃过亏一个终端里的关键命令因为另一个终端退出而被覆盖导致第二天想复盘时历史里没有只能靠 shell 日志补齐。4.3 alias 不生效alias 不生效的情况分几种配置文件没重新加载source ~/.bashrc 即可加载了错误的配置文件登录 shell 读 .bash_profile非登录 shell 读 .bashrc当前是非交互 shellalias 默认不展开别名被系统中同名命令名覆盖某些发行版会在启动环境里定义alias 的覆盖优先级检查手段用 type aliasName它会告诉你这个名字最终会解析到什么。如果你看到的是“xxx is /usr/bin/xxx”而没提 alias说明别名没加载或者被覆盖。这时候先执行 grep -n 别名名 ~/.bashrc确认定义是否存在再确认文件加载顺序。我习惯把所有自定义 alias 放在 ~/.bashrc 末尾并且加注释隔开方便排查。另外提醒一点alias 名字不要太短比如只用 s 代替 ssh 是可以的但如果这机器是别人也要运维的太短的别名会严重影响可读性。我见过有人用 alias sdsystemctl结果新接手的人完全看不懂命令在做什么。4.4 通配符匹配不到但又不报错如果在脚本里用 ls *.log而 .log 文件不存在bash 会把 *.log 原样传给 lsls 报错“No such file or directory”。如果你想在“没有匹配”时优雅地跳过必须用 shopt -s nullglob。还有一种特殊情况文件名里有空格。比如你有一个文件叫 my report.txt当你用 *.txt 匹配它时bash 展开后是两个参数my 和 report.txt而不是一个完整的文件名。这也是为什么好习惯是给文件名加引号。实际操作中我会避免在文件名里用空格用下划线或连字符替代省去一堆引号转义的麻烦。4.5 vim 异常退出后的 swap 文件遇到“.filename.swp already exists”的提示先不要急着删除。你需要判断这个 swap 文件是否对应一个还在运行的 vim 进程。用 pgrep -af vim 查看是不是还有另一个编辑器在打开同一个文件。如果是两路编辑你可以选择只读打开或者强制同时编辑但通常建议先处理另一个会话。如果没有其他 vim 进程那么 swap 文件是上一次崩溃留下的。此时可以根据提示选择 R 恢复未保存的内容恢复完成后退出再删除 swap 文件。恢复成功的标志是文件里能看到你崩溃前的最新修改。若确认不需要恢复直接 rm 同目录下的 .文件名.swp 即可。5. 写在后面的经验教你一个巩固这套技能的方法找一台虚拟机给自己一个任务——模拟日常巡检要求全程用命令行完成限制不许使用方向键不许输入超过三层的绝对路径能用别名就不用全命令。规则看起来苛刻但坚持两周之后你会发现Tab 补全变成了手部肌肉的本能CtrlA、CtrlE 成了手指的默认动作历史命令的感叹号用法不再需要想“这条会不会冲突”而是直接就能勾出想要的命令。我在实际管理服务器时最省时间的习惯反而不是某个单一技巧而是“先想后敲”。敲任何命令之前先在脑子里过一遍这个操作涉及哪些文件、哪些命令中间有没有能用补全、历史、别名、通配符压缩掉的部分。这个思考习惯一旦养成你的命令行效率就真的跨过了一个台阶。RH134 第1章把这个内容放在最前面是有它的道理的。