Shell编程核心入门:参数传递、运算符与流程控制全解析
在Linux/Unix系统中,Shell作为命令解释器和脚本语言,是自动化运维、批量处理任务的核心工具。掌握Shell脚本的参数传递、运算符使用和流程控制,能让你从“手动执行命令”升级为“编写脚本自动完成复杂任务”。本文将结合实例,详细拆解这三大核心知识点,助你快速入门Shell编程。
文章目录
- Shell编程核心入门:参数传递、运算符与流程控制全解析
- 一、Shell参数传递:让脚本更灵活
- 1.1 基础:参数传递与获取方式
- 传递参数的语法
- 脚本内获取参数的语法
- 1.2 关键区别:$* vs $@
- 实例验证
- 2.2 关系运算符:判断数值大小
- 实例:比较两个参数大小
- 2.3 逻辑运算符:组合条件判断
- 实例:判断数值是否在指定范围
- 2.4 文件测试运算符:判断文件属性
- 实例:检查脚本是否可执行
- 三、Shell流程控制:控制脚本执行逻辑
- 3.1 选择结构:根据条件执行不同代码
- 1. if语句:单支、双支、多支判断
- 实例:根据分数判断等级
- 2. case语句:多值匹配判断
- 实例:简单菜单交互
- 四、综合实例:Shell脚本实战
- 五、总结
一、Shell参数传递:让脚本更灵活
在执行Shell脚本时,我们可以通过命令行向脚本传递参数,实现“同一脚本处理不同数据”的需求。比如编写一个计算两个数之和的脚本,通过参数传入不同数字,无需修改脚本即可得到结果。
1.1 基础:参数传递与获取方式
传递参数的语法
执行脚本时,参数紧跟在脚本名后,用空格分隔:
./脚本名 参数1 参数2 参数3 ...
例如:./calc.sh 10 20
表示向calc.sh
脚本传递参数10
和20
。
脚本内获取参数的语法
脚本中通过$n
获取第n
个参数(n
为数字),特殊变量用于获取参数整体信息:
变量 | 含义 | 示例(以上述./calc.sh 10 20 为例) |
---|---|---|
$0 | 当前脚本的文件名 | $0 输出 ./calc.sh |
$1~$n | 第1个到第n个参数 | $1 输出 10 ,$2 输出 20 |
$# | 传递的参数总数 | $# 输出 2 |
$* | 所有参数的集合(作为一个整体字符串) | "$*" 输出 "10 20" |
$@ | 所有参数的集合(作为独立参数列表) | "$@" 输出 "10" "20" |
1.2 关键区别:$* vs $@
$*
和$@
都表示“所有参数”,但被双引号包裹时行为完全不同,这是Shell参数传递的高频考点:
场景 | $*的行为 | $@的行为 |
---|---|---|
不被"" 包裹 | 均以$1 $2 ... $n 形式输出参数列表 | 均以$1 $2 ... $n 形式输出参数列表 |
被"" 包裹 | 合并为一个字符串:"$1 $2 ... $n" | 保持独立参数:"$1" "$2" ... "$n" |
实例验证
创建param_demo.sh
脚本:
#!/bin/bash
echo "=== \$* 演示 ==="
for arg in "$*"; doecho "参数:$arg"
doneecho "=== \$@ 演示 ==="
for arg in "$@"; doecho "参数:$arg"
done
执行脚本:./param_demo.sh 1 2 3
,输出结果:
=== $* 演示 ===
参数:1 2 3
=== $@ 演示 ===
参数:1
参数:2
参数:3
结论:循环处理独立参数时,优先使用"$@"
;需将所有参数作为整体字符串处理时,使用"$*"
。
## 二、Shell运算符:实现脚本的计算与判断
Shell本身不支持直接数学运算,需通过工具(如`expr`)或特殊语法(如`$(( ))`)实现。运算符按功能分为**算术运算符**、**关系运算符**、**逻辑运算符**和**文件测试运算符**。### 2.1 算术运算符:处理数值计算
常用算术运算符:`+`(加)、`-`(减)、`*`(乘)、`/`(除)、`%`(取余)、`++`(自增)、`--`(自减)。#### 实现方式对比
| 方式 | 语法示例 | 说明 |
|--------------|-----------------------------------|---------------------------------------|
| `expr` | `val=`expr 2 + 2`` | 运算符两边必须有空格,用反引号``包裹 |
| `$(( ))` | `val=$((2+2))` | 支持运算符无空格,语法简洁 |
| `$[ ]` | `val=$[2+2]` | 与`$(( ))`类似,兼容性稍差 |
| `let` | `let val=2+2` | 直接计算,无需`$`引用变量 |#### 实例:计算1-10的累加和
```bash
#!/bin/bash
sum=0
for ((i=1; i<=10; i++)); dosum=$((sum + i)) # 或 sum=$[sum+i]
done
echo "1-10累加和:$sum" # 输出 55
2.2 关系运算符:判断数值大小
关系运算符仅支持整数,返回true
(0)或false
(非0),常用于条件判断。
运算符 | 含义 | 示例(a=10 ,b=20 ) |
---|---|---|
-eq | 等于 | [ $a -eq $b ] → false |
-ne | 不等于 | [ $a -ne $b ] → true |
-gt | 大于 | [ $a -gt $b ] → false |
-lt | 小于 | [ $a -lt $b ] → true |
-ge | 大于等于 | [ $a -ge $b ] → false |
-le | 小于等于 | [ $a -le $b ] → true |
实例:比较两个参数大小
#!/bin/bash
a=$1
b=$2
if [ $a -gt $b ]; thenecho "$a > $b"
elif [ $a -lt $b ]; thenecho "$a < $b"
elseecho "$a == $b"
fi
执行:./compare.sh 15 20
→ 输出 15 < 20
。
2.3 逻辑运算符:组合条件判断
用于将多个条件组合,常见有两种语法(注意场景区别):
逻辑关系 | if 语句中语法 | 直接计算语法 | 示例(a=10 ) |
---|---|---|---|
与(and) | -a | && | [ $a -gt 5 -a $a -lt 15 ] → true |
或(or) | -o | ` | |
非(not) | ! | ! | [ ! $a -eq 5 ] → true |
实例:判断数值是否在指定范围
#!/bin/bash
num=$1
if [ $num -ge 0 -a $num -le 100 ]; thenecho "$num 在 0-100 范围内"
elseecho "$num 超出范围"
fi
2.4 文件测试运算符:判断文件属性
Shell脚本常需操作文件(如判断文件是否存在、是否可执行),文件测试运算符是核心工具:
运算符 | 含义 | 示例 |
---|---|---|
-e | 文件/目录是否存在 | [ -e ./test.sh ] |
-f | 是否为普通文件 | [ -f ./test.sh ] |
-d | 是否为目录 | [ -d ./test_dir ] |
-r | 是否可读 | [ -r ./test.sh ] |
-w | 是否可写 | [ -w ./test.sh ] |
-x | 是否可执行 | [ -x ./test.sh ] |
-s | 文件是否非空(大小>0) | [ -s ./test.sh ] |
实例:检查脚本是否可执行
#!/bin/bash
file="./test.sh"
if [ -e $file ]; thenif [ -x $file ]; thenecho "$file 可执行,开始运行..."./$fileelseecho "$file 不可执行,添加执行权限..."chmod +x $filefi
elseecho "$file 不存在!"
fi
三、Shell流程控制:控制脚本执行逻辑
默认情况下,Shell脚本按“从上到下、逐行执行”的顺序运行。流程控制语句可改变执行顺序,分为选择结构(if、case)和循环结构(for、while)。
3.1 选择结构:根据条件执行不同代码
1. if语句:单支、双支、多支判断
-
单支if:条件成立则执行,否则不执行;
if [ 条件 ]; then代码块 fi
-
双支if:条件成立执行代码1,否则执行代码2;
if [ 条件 ]; then代码块1 else代码块2 fi
-
多支if:多条件判断,匹配第一个成立的条件;
if [ 条件1 ]; then代码块1 elif [ 条件2 ]; then代码块2 else默认代码块 fi
实例:根据分数判断等级
#!/bin/bash
score=$1
if [ $score -ge 90 ]; thenecho "优秀"
elif [ $score -ge 80 ]; thenecho "良好"
elif [ $score -ge 60 ]; thenecho "及格"
elseecho "不及格"
fi
执行:./grade.sh 85
→ 输出 良好
。
2. case语句:多值匹配判断
当需要匹配“固定的多个值”时(如菜单选择),case
比if-elif
更简洁,语法如下:
case $变量 in模式1)代码块1;; # 结束当前模式模式2)代码块2;;*) # 默认模式(无匹配时执行)默认代码块;;
esac # case的反写,标志结束
实例:简单菜单交互
#!/bin/bash
echo "请选择操作:1.查看日期 2.查看目录 3.退出"
read choice # 读取用户输入
case $choice in1)date;;2)ls;;3)echo "退出程序"exit 0 # 退出脚本;;*)echo "无效选择";;
esac
四、综合实例:Shell脚本实战
结合上述知识点,编写一个“批量文件重命名”脚本:需求是将当前目录下所有.txt
文件重命名为file_1.txt
、file_2.txt
…
#!/bin/bash
# 批量重命名.txt文件
count=1 # 计数器,用于文件名编号# 遍历当前目录下的.txt文件
for file in *.txt; do# 判断是否为普通文件(避免目录干扰)if [ -f $file ]; then# 重命名文件mv $file "file_$count.txt"echo "已重命名:$file → file_$count.txt"count=$((count + 1)) # 计数器自增fi
doneecho "重命名完成,共处理 $((count-1)) 个文件"
五、总结
Shell编程的核心是“通过参数传递实现灵活性、通过运算符实现计算判断、通过流程控制实现逻辑跳转”。掌握本文的三大知识点后,你可以:
- 编写支持命令行参数的脚本;
- 实现数值计算、文件判断等核心功能;
- 用流程控制语句处理复杂逻辑(如批量任务、交互菜单)。
建议从“小脚本”开始练习(如文件备份、日志清理),逐步积累实战经验,最终实现Shell自动化运维的目标!