Bash Shell命令详解:从基础操作到高级脚本编写
1. Shell命令基础:Bash的核心操作单元
在Linux和Unix-like系统中,Shell命令是与操作系统交互的基本方式。作为Bash学习的核心章节,理解Shell命令的工作原理和分类对提升命令行效率至关重要。我刚开始接触Bash时,常常混淆内置命令和外部程序的区别,直到系统性地学习后才明白它们各自的特性和适用场景。
Shell命令主要分为三种类型:
- 可执行程序:存储在/bin、/usr/bin等目录下的独立程序文件
- Shell内置命令:直接内置于Bash解释器中的命令
- Shell函数:用户自定义的命令序列
提示:使用
type命令可以快速判断一个命令的类型,例如type cd会显示"cd is a shell builtin"。
1.1 命令执行的基本流程
当你在Shell中输入一个命令并按下回车时,Bash会按照以下顺序处理:
- 解析命令行:将输入分解为命令名和参数
- 别名扩展:检查是否有对应的命令别名
- 判断命令类型:
- 先检查是否为内置命令
- 若不是,则在$PATH环境变量指定的目录中查找可执行文件
- 执行命令:
- 内置命令直接由Bash解释器执行
- 外部程序则创建新进程执行
这个流程解释了为什么有些命令在不同Shell中表现不同,也说明了环境变量$PATH的重要性。我在管理服务器时曾遇到"command not found"错误,后来发现是因为PATH变量被意外修改导致的。
1.2 命令参数与选项的规范
Shell命令通常遵循一定的参数传递规范:
- 短选项:单字母选项,前面带一个连字符(如
-l) - 长选项:完整单词选项,前面带两个连字符(如
--help) - 参数:选项后面跟的具体值(如
-f filename)
现代GNU工具通常同时支持短选项和长选项,而BSD系工具可能只支持短选项。了解这些差异可以避免在不同系统间迁移脚本时出现问题。
2. 关键Shell命令深度解析
2.1 文件操作三剑客:ls、cp、mv
ls命令的进阶用法:
# 按文件大小排序显示(带人类可读格式) ls -lhS # 显示inode号和文件类型标识符 ls -iF # 递归列出子目录内容,并显示完整路径 ls -lR | grep '^/'cp命令的注意事项:
- 使用
-a选项可以保留所有文件属性(相当于-dR --preserve=all) - 在复制大量小文件时,考虑使用
rsync效率更高 - 使用
-i选项可以在覆盖前提示确认
mv命令的特别行为:
- 跨文件系统移动实际上是"复制+删除"操作
- 原子性重命名操作(同文件系统内)是它的独特优势
2.2 文本处理利器:grep、sed、awk
grep家族命令对比:
| 命令 | 特点 | 典型使用场景 |
|---|---|---|
| grep | 基础正则表达式 | 简单文本匹配 |
| egrep | 扩展正则表达式 | 复杂模式匹配 |
| fgrep | 固定字符串匹配 | 精确字符串查找 |
| rgrep | 递归目录搜索 | 项目代码全局搜索 |
sed的实用技巧:
# 就地编辑文件(BSD和GNU版本参数不同) sed -i.bak 's/old/new/g' file.txt # GNU版本 sed -i '' 's/old/new/g' file.txt # BSD版本 # 只打印匹配行之后的5行 sed -n '/pattern/,+5p' fileawk的字段处理:
# 统计第3列的总和 awk '{sum+=$3} END{print sum}' data.txt # 根据条件格式化输出 awk '$3>100 {printf "%-10s %8.2f\n", $1, $3}' data.txt3. 进程管理与系统监控命令
3.1 进程控制命令详解
ps命令的输出解读:
ps aux:BSD风格,显示所有用户进程ps -ef:UNIX风格,显示完整格式ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu:自定义输出字段
top/htop的实用技巧:
- 在top中按
M按内存排序,按P按CPU排序 - 按
c显示完整命令路径 - 按
1展开多核CPU显示 - htop支持鼠标操作和更直观的界面
kill信号的正确使用:
| 信号编号 | 信号名 | 作用 | 使用场景 |
|---|---|---|---|
| 1 | SIGHUP | 挂起 | 重新加载配置文件 |
| 2 | SIGINT | 中断(Ctrl+C) | 交互式程序终止 |
| 9 | SIGKILL | 强制终止 | 无法正常终止的进程 |
| 15 | SIGTERM | 优雅终止(默认) | 正常关闭进程 |
3.2 系统资源监控
free命令的内存分析:
free -h # 人类可读格式 free -s 5 # 每5秒刷新一次关键指标解读:
available:实际可用内存(比free更准确)buff/cache:被缓冲和缓存占用的内存(必要时可释放)
iostat的磁盘监控:
iostat -dx 2 # 每2秒显示一次详细磁盘统计重点关注指标:
%util:设备利用率(接近100%表示饱和)await:平均I/O等待时间(毫秒)
4. 网络相关命令实战
4.1 网络诊断工具
curl的进阶用法:
# 显示详细请求过程 curl -v https://example.com # 跟随重定向并保存最终内容 curl -L -o output.html https://example.com # 发送POST请求带JSON数据 curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' https://api.example.comssh的配置优化:
# ~/.ssh/config示例 Host myserver HostName server.example.com User myuser Port 2222 IdentityFile ~/.ssh/myserver_key TCPKeepAlive yes ServerAliveInterval 604.2 防火墙与路由
iptables基础规则:
# 允许已建立的连接 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 开放SSH端口 iptables -A INPUT -p tcp --dport 22 -j ACCEPT # 默认拒绝策略 iptables -P INPUT DROP路由诊断命令:
# 显示路由表 ip route show # 跟踪到达目标的路由路径 traceroute example.com # 测试MTU大小 ping -M do -s 1472 example.com # 逐步减小1472直到成功5. Shell命令的组合与脚本化
5.1 命令组合技巧
管道连接的黄金组合:
# 查找最近修改的10个日志文件 find /var/log -name "*.log" -type f -mtime -7 | xargs ls -lt | head -10 # 统计不同HTTP状态码的出现次数 cat access.log | awk '{print $9}' | sort | uniq -c | sort -nr进程替换的高级用法:
# 比较两个命令的输出 diff <(ls /dir1) <(ls /dir2) # 将多个命令输出合并处理 paste <(cmd1) <(cmd2) > combined.txt5.2 脚本编写最佳实践
安全脚本编写原则:
- 总是在脚本开头设置
set -euo pipefail - 使用
[[ ]]代替[ ]进行条件测试 - 变量引用加双引号,如
"$var" - 使用
$(cmd)而不是反引号`cmd` - 对用户输入进行验证和转义
错误处理模式:
#!/bin/bash set -euo pipefail # 定义错误处理函数 err_handler() { echo "Error on line $1" >&2 exit 1 } trap 'err_handler $LINENO' ERR # 主脚本逻辑 tempfile=$(mktemp) cleanup() { rm -f "$tempfile"; } trap cleanup EXIT # 脚本主体...掌握这些Shell命令的核心用法和组合技巧,可以显著提升在命令行环境下的工作效率。在实际使用中,建议结合man手册和--help选项不断探索各命令的更多可能性。
