课程概览与 Shell
终端与 Shell
- 终端与 Shell 的分工
- 硬件终端:VT100、ASR-33
- Terminal 的词源:线路的末端
- Teletypewriter、TTY 与
tty命令 - 终端模拟器与 VT100 控制码
- Shell 的读入循环
- 命令、参数与
argv - 提示符的构成
- 绝对路径与相对路径
.、..、~,根目录的..仍是根Tab补全:单次补全、双次列候选zoxide按访问历史跳目录
一条命令的旅程
- 切词
- 引号:单引号、双引号、反斜杠、
$'...' - 变量、
${}与export - 命令替换
$() - 变量展开后的二次切词
- 文件名展开(glob)
*、?、[]与隐藏文件- brace expansion
{a,b} - 递归匹配
**与 globstar - 无匹配时的行为
- glob 与正则
$PATH的查找顺序与which -a- 内建命令与
type -a fork+exec+waitcd、export为什么必须是内建
打开终端后发生了什么
- 终端、Shell、内核的分工
- 文件描述符 0/1/2
- 一切皆文件
fork/exec与 fd 继承- 查看 fd:
/proc/$$/fd与lsof - 伪终端:master 与 slave
- 启动链与
forkpty - 一次按键的旅程
- 行规程、规范模式与
stty - 控制键:
Ctrl-C、Ctrl-\、Ctrl-Z、Ctrl-D - raw 模式与全屏程序
- 关闭窗口与
SIGHUP nohup、disown与tmux
重定向和管道
- 重定向的本质:改 fd 指向
>、>>、<、2>、&>与/dev/null2>&1的顺序- 截断与
noclobber、>| exec持久重定向sudo与重定向- 管道与内核缓冲区
- 管道的并发、反压与 EOF
SIGPIPE与退出码 141PIPESTATUS与pipefail- stderr 进管道与
tee - 行缓冲、全缓冲、无缓冲
stdbuf、--line-buffered、unbuffer- 案例:sshd 断开连接统计
bash 编程与脚本
- 返回码与
$? &&与||if/else/fiwhile read与-rfor循环test与[ ][[ ]]与模式匹配- 字符串比较与数值比较
- 位置参数:
$0、$1、$#、$@ "$@"为什么要加引号- shebang 与
/usr/bin/env set -euo pipefailset -xchmod +x与./script.sh- 权限位:
rwx、755 chmod与chown- 后台任务:
&、$!、kill - 反复运行测试的脚本
- shellcheck
常用文本工具
man、--help、tldrcat、less、head、tailsort与uniqsort默认字典序,数字比较用-nfind的-maxdepth要写在测试条件之前grepsedfindawk
容易混淆的问题
$SHELL、$0与ps -p $$$TERM与终端能力- 终端里跑非 Shell 程序
- 无终端环境:脚本、CI、
ssh host cmd Ctrl-C的完整链路if与[$?与$!./script.sh与PATH