mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5
701 字
2 分钟
Linux操作大全(七):Shell脚本编程详解
2026-05-25

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=24
PI=3.14159
# 使用变量
echo $name
echo ${name}
# 变量拼接
greeting="Hello, ${name}!"
echo $greeting

2.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"' >> ~/.bashrc
source ~/.bashrc

常用环境变量

变量说明
$HOME用户家目录
$USER当前用户名
$PATH命令搜索路径
$SHELL当前Shell
$PWD当前目录
$HOSTNAME主机名

2.4 只读变量#

readonly PI=3.14159
PI=3.14 # 报错:readonly variable

2.5 删除变量#

unset name
echo $name # 输出为空

三、字符串操作#

3.1 字符串定义#

# 单引号(原样输出)
str1='Hello $name'
# 双引号(解析变量)
str2="Hello $name"
echo $str1 # 输出:Hello $name
echo $str2 # 输出:Hello Linux

3.2 字符串长度#

str="Hello"
echo ${#str} # 输出:5

3.3 字符串截取#

str="Hello World"
# 从第1个字符开始截取5个
echo ${str:0:5} # 输出:Hello
# 从第6个字符开始截取
echo ${str:6} # 输出:World

3.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 定义数组#

# 方法1
arr=(apple banana cherry)
# 方法2
arr[0]=apple
arr[1]=banana
arr[2]=cherry

4.2 访问数组#

# 访问单个元素
echo ${arr[0]} # 输出:apple
echo ${arr[1]} # 输出:banana
# 访问所有元素
echo ${arr[@]} # 输出:apple banana cherry
# 数组长度
echo ${#arr[@]} # 输出:3

4.3 数组操作#

# 添加元素
arr+=(date elderberry)
# 删除元素
unset arr[1]
# 切片
echo ${arr[@]:1:2} # 从索引1开始取2个

五、运算符#

5.1 算术运算#

a=10
b=20
# 方法1:expr(注意空格)
c=`expr $a + $b`
# 方法2:$((...))
c=$((a + b))
c=$((a - b))
c=$((a * b))
c=$((a / b))
c=$((a % b))
# 方法3:let
let c=a+b
echo $c

5.2 关系运算#

a=10
b=20
if [ $a -eq $b ]; then echo "相等"; fi
if [ $a -ne $b ]; then echo "不相等"; fi
if [ $a -gt $b ]; then echo "大于"; fi
if [ $a -lt $b ]; then echo "小于"; fi
if [ $a -ge $b ]; then echo "大于等于"; fi
if [ $a -le $b ]; then echo "小于等于"; fi

5.3 字符串运算#

a="hello"
b="world"
if [ $a = $b ]; then echo "相等"; fi
if [ $a != $b ]; then echo "不相等"; fi
if [ -z $a ]; then echo "为空"; fi
if [ -n $a ]; then echo "不为空"; fi

5.4 逻辑运算#

a=10
b=20
if [ $a -lt 100 ] && [ $b -gt 100 ]; then echo "AND"; fi
if [ $a -lt 100 ] || [ $b -gt 100 ]; then echo "OR"; fi
if [ ! false ]; then echo "NOT"; fi

六、流程控制#

6.1 if语句#

# 基本if
if [ condition ]; then
commands
fi
# if-else
if [ condition ]; then
commands1
else
commands2
fi
# if-elif-else
if [ condition1 ]; then
commands1
elif [ condition2 ]; then
commands2
else
commands3
fi

示例

#!/bin/bash
age=18
if [ $age -ge 18 ]; then
echo "成年人"
else
echo "未成年人"
fi

6.2 case语句#

#!/bin/bash
fruit="apple"
case $fruit in
"apple")
echo "苹果"
;;
"banana")
echo "香蕉"
;;
"cherry")
echo "樱桃"
;;
*)
echo "未知水果"
;;
esac

6.3 for循环#

# 基本for
for i in 1 2 3 4 5; do
echo $i
done
# 范围
for i in {1..5}; do
echo $i
done
# C风格
for ((i=0; i<5; i++)); do
echo $i
done
# 遍历数组
arr=(apple banana cherry)
for item in ${arr[@]}; do
echo $item
done
# 遍历文件
for file in /home/user/*.txt; do
echo $file
done

6.4 while循环#

#!/bin/bash
count=0
while [ $count -lt 5 ]; do
echo $count
count=$((count + 1))
done

6.5 until循环#

#!/bin/bash
count=0
until [ $count -ge 5 ]; do
echo $count
count=$((count + 1))
done

6.6 break和continue#

# break:跳出循环
for i in {1..10}; do
if [ $i -eq 5 ]; then
break
fi
echo $i
done
# continue:跳过本次循环
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue
fi
echo $i
done

七、函数#

7.1 函数定义#

# 方法1
function greet() {
echo "Hello, $1!"
}
# 方法2
greet() {
echo "Hello, $1!"
}
# 调用函数
greet "Linux"

7.2 函数参数#

add() {
local result=$(($1 + $2))
echo $result
}
sum=$(add 10 20)
echo $sum # 输出:30

7.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:echo
get_name() {
echo "Linux"
}
name=$(get_name)
echo $name

7.4 局部变量#

my_func() {
local local_var="I am local"
global_var="I am global"
}
my_func
echo $local_var # 输出为空
echo $global_var # 输出:I am global

八、输入输出#

8.1 读取输入#

# 基本读取
echo "请输入名字:"
read name
echo "你好,$name"
# 带提示的读取
read -p "请输入名字:" name
# 读取密码(不显示)
read -s -p "请输入密码:" password
# 读取多个变量
read -p "输入姓名和年龄:" name age
echo "$name, $age岁"
# 设置超时
read -t 5 -p "5秒内输入:" input

8.2 输出重定向#

# 覆盖写入文件
echo "Hello" > file.txt
# 追加写入文件
echo "World" >> file.txt
# 错误重定向
command 2> error.log
# 同时重定向标准输出和错误
command > output.log 2>&1
command &> all.log
# 丢弃输出
command > /dev/null 2>&1

8.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 -tuln

9.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}"
;;
esac

9.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"
fi
done

9.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.gz

10.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.txt

10.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/bash
set -x # 开启调试
# ... 脚本内容
set +x # 关闭调试

10.2 错误处理#

#!/bin/bash
set -e # 遇到错误立即退出
set -u # 使用未定义变量报错
set -o pipefail # 管道中任意命令失败则失败
# 或者使用trap
trap 'echo "错误发生在第 $LINENO 行"' ERR

十一、总结#

本章学习了:

  1. Shell基础:脚本定义、运行方式
  2. 变量:定义、特殊变量、环境变量
  3. 字符串:定义、长度、截取、替换
  4. 数组:定义、访问、操作
  5. 运算符:算术、关系、逻辑
  6. 流程控制:if、case、for、while
  7. 函数:定义、参数、返回值
  8. 输入输出:read、重定向、管道
  9. 实战脚本:备份、监控、日志分析

下一章预告:《Linux操作大全(八):磁盘与存储管理详解》


如有疑问或发现错误,欢迎在评论区指出!

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Linux操作大全(七):Shell脚本编程详解
https://emilia520.icu/posts/linux-manual-07-shell/
作者
火花花
发布于
2026-05-25
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录