701 字
2 分钟
Linux操作大全(七):Shell脚本编程详解
Linux操作大全(七):Shell脚本编程详解
本文是Linux操作大全系列的第七篇,详细讲解Shell脚本编程。
一、Shell基础
1.1 什么是Shell?
Shell是Linux的命令解释器,接收用户输入的命令并执行。常见的Shell:
- bash:最常用,Ubuntu默认
- sh:Bourne Shell,最古老的Shell
- zsh:功能更强,macOS默认
- fish:用户友好,自动补全
1.2 第一个Shell脚本
#!/bin/bash# 这是注释<a id="echo"></a>echo "Hello, World!"说明:
#!/bin/bash:指定解释器(必须在第一行)#:注释echo:输出文字
运行脚本:
# 方法1:添加执行权限chmod +x script.sh./script.sh
# 方法2:使用bash命令bash script.sh<a id="source"></a>
# 方法3:使用source命令(在当前shell执行)source script.sh二、变量
2.1 变量定义
# 定义变量(等号两边不能有空格!)name="Linux"version=24PI=3.14159
# 使用变量echo $nameecho ${name}
# 变量拼接greeting="Hello, ${name}!"echo $greeting2.2 特殊变量
echo "脚本名: $0"echo "第一个参数: $1"echo "第二个参数: $2"echo "参数个数: $#"echo "所有参数: $@"echo "所有参数: $*"echo "上一个命令的退出状态: $$"echo "后台运行的最后一个进程ID: $!"2.3 环境变量
# 查看所有环境变量env
<a id="export"></a># 设置环境变量export MY_VAR="hello"
# 永久设置(添加到~/.bashrc)echo 'export MY_VAR="hello"' >> ~/.bashrcsource ~/.bashrc常用环境变量:
| 变量 | 说明 |
|---|---|
$HOME | 用户家目录 |
$USER | 当前用户名 |
$PATH | 命令搜索路径 |
$SHELL | 当前Shell |
$PWD | 当前目录 |
$HOSTNAME | 主机名 |
2.4 只读变量
readonly PI=3.14159PI=3.14 # 报错:readonly variable2.5 删除变量
unset nameecho $name # 输出为空三、字符串操作
3.1 字符串定义
# 单引号(原样输出)str1='Hello $name'
# 双引号(解析变量)str2="Hello $name"
echo $str1 # 输出:Hello $nameecho $str2 # 输出:Hello Linux3.2 字符串长度
str="Hello"echo ${#str} # 输出:53.3 字符串截取
str="Hello World"
# 从第1个字符开始截取5个echo ${str:0:5} # 输出:Hello
# 从第6个字符开始截取echo ${str:6} # 输出:World3.4 字符串替换
str="Hello World World"
# 替换第一个echo ${str/World/Linux} # 输出:Hello Linux World
# 替换所有echo ${str//World/Linux} # 输出:Hello Linux Linux
# 删除匹配echo ${str/World/} # 输出:Hello World四、数组
4.1 定义数组
# 方法1arr=(apple banana cherry)
# 方法2arr[0]=applearr[1]=bananaarr[2]=cherry4.2 访问数组
# 访问单个元素echo ${arr[0]} # 输出:appleecho ${arr[1]} # 输出:banana
# 访问所有元素echo ${arr[@]} # 输出:apple banana cherry
# 数组长度echo ${#arr[@]} # 输出:34.3 数组操作
# 添加元素arr+=(date elderberry)
# 删除元素unset arr[1]
# 切片echo ${arr[@]:1:2} # 从索引1开始取2个五、运算符
5.1 算术运算
a=10b=20
# 方法1:expr(注意空格)c=`expr $a + $b`
# 方法2:$((...))c=$((a + b))c=$((a - b))c=$((a * b))c=$((a / b))c=$((a % b))
# 方法3:letlet c=a+b
echo $c5.2 关系运算
a=10b=20
if [ $a -eq $b ]; then echo "相等"; fiif [ $a -ne $b ]; then echo "不相等"; fiif [ $a -gt $b ]; then echo "大于"; fiif [ $a -lt $b ]; then echo "小于"; fiif [ $a -ge $b ]; then echo "大于等于"; fiif [ $a -le $b ]; then echo "小于等于"; fi5.3 字符串运算
a="hello"b="world"
if [ $a = $b ]; then echo "相等"; fiif [ $a != $b ]; then echo "不相等"; fiif [ -z $a ]; then echo "为空"; fiif [ -n $a ]; then echo "不为空"; fi5.4 逻辑运算
a=10b=20
if [ $a -lt 100 ] && [ $b -gt 100 ]; then echo "AND"; fiif [ $a -lt 100 ] || [ $b -gt 100 ]; then echo "OR"; fiif [ ! false ]; then echo "NOT"; fi六、流程控制
6.1 if语句
# 基本ifif [ condition ]; then commandsfi
# if-elseif [ condition ]; then commands1else commands2fi
# if-elif-elseif [ condition1 ]; then commands1elif [ condition2 ]; then commands2else commands3fi示例:
#!/bin/bashage=18
if [ $age -ge 18 ]; then echo "成年人"else echo "未成年人"fi6.2 case语句
#!/bin/bashfruit="apple"
case $fruit in "apple") echo "苹果" ;; "banana") echo "香蕉" ;; "cherry") echo "樱桃" ;; *) echo "未知水果" ;;esac6.3 for循环
# 基本forfor i in 1 2 3 4 5; do echo $idone
# 范围for i in {1..5}; do echo $idone
# C风格for ((i=0; i<5; i++)); do echo $idone
# 遍历数组arr=(apple banana cherry)for item in ${arr[@]}; do echo $itemdone
# 遍历文件for file in /home/user/*.txt; do echo $filedone6.4 while循环
#!/bin/bashcount=0
while [ $count -lt 5 ]; do echo $count count=$((count + 1))done6.5 until循环
#!/bin/bashcount=0
until [ $count -ge 5 ]; do echo $count count=$((count + 1))done6.6 break和continue
# break:跳出循环for i in {1..10}; do if [ $i -eq 5 ]; then break fi echo $idone
# continue:跳过本次循环for i in {1..10}; do if [ $i -eq 5 ]; then continue fi echo $idone七、函数
7.1 函数定义
# 方法1function greet() { echo "Hello, $1!"}
# 方法2greet() { echo "Hello, $1!"}
# 调用函数greet "Linux"7.2 函数参数
add() { local result=$(($1 + $2)) echo $result}
sum=$(add 10 20)echo $sum # 输出:307.3 函数返回值
# 方法1:return(只能返回0-255)is_even() { if [ $(($1 % 2)) -eq 0 ]; then return 0 else return 1 fi}
if is_even 4; then echo "偶数"fi
# 方法2:echoget_name() { echo "Linux"}
name=$(get_name)echo $name7.4 局部变量
my_func() { local local_var="I am local" global_var="I am global"}
my_funcecho $local_var # 输出为空echo $global_var # 输出:I am global八、输入输出
8.1 读取输入
# 基本读取echo "请输入名字:"read nameecho "你好,$name"
# 带提示的读取read -p "请输入名字:" name
# 读取密码(不显示)read -s -p "请输入密码:" password
# 读取多个变量read -p "输入姓名和年龄:" name ageecho "$name, $age岁"
# 设置超时read -t 5 -p "5秒内输入:" input8.2 输出重定向
# 覆盖写入文件echo "Hello" > file.txt
# 追加写入文件echo "World" >> file.txt
# 错误重定向command 2> error.log
# 同时重定向标准输出和错误command > output.log 2>&1command &> all.log
# 丢弃输出command > /dev/null 2>&18.3 管道
# 基本管道ls -la | grep ".txt"
# 多级管道cat file.txt | grep "error" | wc -l<a id="sort"></a>
# 排序去重cat file.txt | sort | uniq九、实战脚本
9.1 自动备份脚本
#!/bin/bash# backup.sh - 自动备份脚本
BACKUP_DIR="/backup"DATE=$(date +%Y%m%d_%H%M%S)SOURCE_DIR="/home/user/data"
# 创建备份目录mkdir -p $BACKUP_DIR
# 执行备份tar -czf $BACKUP_DIR/backup_$DATE.tar.gz $SOURCE_DIR
# 删除7天前的备份find $BACKUP_DIR -name "backup_*.tar.gz" -mtime +7 -delete
echo "备份完成:backup_$DATE.tar.gz"9.2 系统监控脚本
#!/bin/bash# monitor.sh - 系统监控脚本
echo "=== 系统信息 ==="echo "主机名:$(hostname)"echo "系统:$(uname -a)"echo "运行时间:$(uptime)"
echo ""echo "=== CPU使用率 ==="<a id="awk"></a>top -bn1 | grep "Cpu(s)" | awk '{print $2}'
echo ""echo "=== 内存使用 ==="free -h
echo ""echo "=== 磁盘使用 ==="df -h
echo ""echo "=== 网络连接 ==="ss -tuln9.3 用户管理脚本
#!/bin/bash# user_manage.sh - 用户管理脚本
case $1 in "add") read -p "用户名:" username read -s -p "密码:" password sudo useradd -m $username echo "$username:$password" | sudo chpasswd echo "用户 $username 创建成功" ;; "delete") read -p "用户名:" username sudo userdel -r $username echo "用户 $username 删除成功" ;; "list") cat /etc/passwd | grep -v nologin | grep -v /bin/false ;; *) echo "用法:$0 {add|delete|list}" ;;esac9.4 服务监控脚本
#!/bin/bash# service_check.sh - 服务监控脚本
SERVICES="nginx mysql sshd"
for service in $SERVICES; do if systemctl is-active --quiet $service; then echo "✅ $service 运行中" else echo "❌ $service 未运行" # 自动重启 sudo systemctl start $service echo "已尝试重启 $service" fidone9.5 日志分析脚本
#!/bin/bash# log_analysis.sh - 日志分析脚本
LOG_FILE="/var/log/nginx/access.log"
echo "=== 访问量统计 ==="wc -l $LOG_FILE
echo ""echo "=== 最常访问的IP ==="awk '{print $1}' $LOG_FILE | sort | uniq -c | sort -rn | head -10
echo ""echo "=== 最常访问的页面 ==="awk '{print $7}' $LOG_FILE | sort | uniq -c | sort -rn | head -10
echo ""echo "=== 404错误 ==="grep "404" $LOG_FILE | wc -l十、常用工具命令
10.1 参数传递:xargs
xargs 将标准输入转换为命令参数。
# 基本用法echo "file1 file2 file3" | xargs rm
# 指定每次传递的参数个数echo "1 2 3 4 5 6" | xargs -n 2 echo
# 处理包含空格的文件名find . -name "*.txt" -print0 | xargs -0 rm
# 交互式确认echo "file1 file2" | xargs -p rm
# 替换占位符echo "file1 file2" | xargs -I {} cp {} /backup/
# 与find配合find . -name "*.log" | xargs grep "error"实用场景:
# 批量删除文件find /tmp -name "*.tmp" | xargs rm -f
# 批量修改权限find . -name "*.sh" | xargs chmod +x
# 批量压缩find . -name "*.txt" | xargs tar -czf texts.tar.gz10.2 输出分流:tee
tee 将输出同时显示到屏幕和写入文件。
# 基本用法:输出到屏幕和文件echo "Hello" | tee output.txt
# 追加到文件echo "World" | tee -a output.txt
# 配合管道使用ls -la | tee file_list.txt | wc -l
# 记录命令输出ping google.com | tee ping_log.txt
# 同时记录标准输出和错误输出command 2>&1 | tee output.log实用场景:
# 安装软件时记录日志sudo apt install nginx | tee install.log
# 编译时记录输出make 2>&1 | tee build.log
# 查看并保存磁盘信息df -h | tee disk_info.txt10.3 循环监控:watch
watch 定期执行命令并刷新显示,用于实时监控。
# 每2秒刷新(默认)watch df -h
# 每5秒刷新watch -n 5 free -h
# 高亮变化的部分watch -d df -h
# 监控文件变化watch -d -n 1 ls -la /var/log/
# 监控网络连接watch -n 1 'ss -tuln | wc -l'
# 监控进程watch -n 1 'ps aux | grep nginx'实用场景:
# 监控磁盘使用watch df -h
# 监控内存watch -n 1 free -h
# 监控日志增长watch -n 1 wc -l /var/log/syslog
# 监控Docker容器watch docker ps十一、调试技巧
10.1 调试选项
# 语法检查bash -n script.sh
# 跟踪执行bash -x script.sh
# 在脚本中开启调试#!/bin/bashset -x # 开启调试# ... 脚本内容set +x # 关闭调试10.2 错误处理
#!/bin/bashset -e # 遇到错误立即退出set -u # 使用未定义变量报错set -o pipefail # 管道中任意命令失败则失败
# 或者使用traptrap 'echo "错误发生在第 $LINENO 行"' ERR十一、总结
本章学习了:
- Shell基础:脚本定义、运行方式
- 变量:定义、特殊变量、环境变量
- 字符串:定义、长度、截取、替换
- 数组:定义、访问、操作
- 运算符:算术、关系、逻辑
- 流程控制:if、case、for、while
- 函数:定义、参数、返回值
- 输入输出:read、重定向、管道
- 实战脚本:备份、监控、日志分析
下一章预告:《Linux操作大全(八):磁盘与存储管理详解》
如有疑问或发现错误,欢迎在评论区指出!
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Linux操作大全(七):Shell脚本编程详解
https://emilia520.icu/posts/linux-manual-07-shell/ 部分信息可能已经过时
相关文章 智能推荐
1
Linux操作大全(二):文件与目录操作详解
Linux常见操作 详细讲解Linux文件和目录的各种操作,包括创建、复制、移动、删除、查找、压缩等,每个命令都有实际示例
2
Linux操作大全(三):用户与权限管理详解
Linux常见操作 深入讲解Linux用户管理、组管理、sudo权限、PAM认证等知识,让你彻底搞懂Linux的权限体系
3
Linux操作大全(四):软件包管理详解
Linux常见操作 全面讲解Linux软件包管理,包括apt、yum、dnf、snap、源码编译安装等,让你轻松管理Linux上的软件
4
Linux操作大全(五):网络配置与管理详解
Linux常见操作 全面讲解Linux网络配置,包括IP地址、DNS、防火墙、SSH、网络诊断等知识,让你轻松管理Linux网络
5
Linux操作大全(六):进程管理与服务管理详解
Linux常见操作 全面讲解Linux进程管理、服务管理、systemd、定时任务等知识,让你轻松掌控系统运行状态








