Shell 脚本编程:循环与函数
一、while 循环
在 Linux shell 脚本中,while 循环是一种基本的控制流结构,它允许重复执行一段代码,直到指定的条件不再满足为止。适用于事先不知道需要循环多少次,但知道何时停止的情况。
基本语法
while [ 条件表达式 ]
do
# 执行命令
done
示例
示例 1:打印数字 1 到 5
#!/bin/bash
counter=1
while [ $counter -le 5 ]
do
echo "The number is $counter"
((counter++))
done
示例 2:读取文件内容
#!/bin/bash
while IFS= read -r line
do
echo "$line"
done < "filename.txt"
示例 3:无限循环
#!/bin/bash
while true
do
echo "This is an infinite loop."
sleep 1
done
注意事项
- 确保条件表达式逻辑正确,避免无限循环
- 处理文件时使用
IFS=和-r选项避免意外行为 - 在循环中适当更新条件变量,确保循环最终停止
两种死循环写法
# 写法 1
while true; do
# commands
done
# 写法 2
while :; do
# commands
done
while read 语法(逐行处理)
while read 变量; do
# 处理逻辑
done
二、until 循环
until 循环持续执行循环体内的代码,直到给定条件为真时停止(与 while 循环相反)。
定义与特点
- 定义:持续执行直到条件为真
- 特点:
- 无需知道具体循环次数
- 当条件满足时自动停止
- 在 Ruby、Bash 等语言中广泛应用
语法结构
# 格式 1
until [ condition ]
do
# 执行的命令
done
# 格式 2
until (( condition ))
do
# 执行的命令
done
工作原理
- 每次迭代开始时检查条件
- 条件为假(返回 0)时执行循环体
- 条件为真(返回非 0)时退出循环
示例
示例 1:打印数字 1 到 5
#!/bin/bash
count=1
until [ $count -gt 5 ]
do
echo "Count: $count"
((count++))
done
示例 2:计算 1 到 100 的总和
#!/bin/bash
all_sum=0
i=1
until ((i>100))
do
let all_sum+=i
let i++
done
echo "所有数据之和: $all_sum"
示例 3:等待文件被创建
#!/bin/bash
until [ -f /tmp/somefile ]
do
echo "Waiting for file to be created..."
sleep 2
done
echo "File created!"
注意事项
- 确保退出条件正确且最终可达
- 保持循环体简单,避免过度嵌套
- 无限循环需确保有退出机制
1 加到 100 的几种写法
# 写法 1 (until)
sum=0; i=1; until ((i>100)); do ((sum+=i)); ((i++)); done; echo $sum
# 写法 2 (while)
sum=0; i=1; while ((i<=100)); do ((sum+=i)); ((i++)); done; echo $sum
# 写法 3 (for)
sum=0; for ((i=1;i<=100;i++)); do ((sum+=i)); done; echo $sum
三、循环中断语句
1. break 命令
立即退出整个循环
for i in {1..10}; do
if [ $i -eq 5 ]; then
break
fi
echo "i is $i"
done
2. continue 命令
跳过当前迭代,继续下一次
for i in {1..10}; do
if [ $((i % 2)) -eq 0 ]; then
continue
fi
echo "Odd number: $i"
done
3. exit 命令
退出整个脚本(慎用)
for i in {1..10}; do
if [ $i -eq 5 ]; then
exit 0
fi
echo "i is $i"
done
4. 条件判断
配合 if 语句控制流程
5. return 命令(函数内部)
退出当前函数
my_function() {
for i in {1..10}; do
if [ $i -eq 5 ]; then
return 0
fi
echo "i is $i"
done
}
四、shift 命令
调整位置参数的位置,每次执行向左移动参数
基本用法
#!/bin/bash
echo "Original arguments: $@"
shift
echo "After one shift: $@"
带参数的 shift
#!/bin/bash
echo "Original arguments: $@"
shift 2
echo "After two shifts: $@"
循环中使用 shift
#!/bin/bash
while [ $# -gt 0 ]; do
echo "Argument: $1"
shift
done
五、select 语句
提供简单的菜单系统供用户选择
基本语法
select 变量 in 选项列表
do
case $变量 in
# 处理逻辑
esac
done
示例
#!/bin/bash
PS3="请选择一个选项: "
echo "菜单:"
select var in "选项1" "选项2" "选项3" "退出"
do
case $var in
"选项1") echo "你选择了选项1" ;;
"选项2") echo "你选择了选项2" ;;
"选项3") echo "你选择了选项3" ;;
"退出") echo "退出选择"; break ;;
*) echo "无效的选择,请重试" ;;
esac
done
六、函数
将命令序列封装为可重用代码块
定义方式
方式 1(推荐)
function_name() {
# 函数体
command1
command2
}
方式 2(简洁)
function_name() { command1; command2; ...; }
方式 3(POSIX 标准)
function_name {
command1
command2
}
函数调用
function_name arg1 arg2 ...
函数调用路径写法
# 获取项目根路径
project_root=$(pwd)
# 调用相对路径脚本
source "${project_root}/path/to/script.sh"
示例
add_numbers() {
local num1=$1
local num2=$2
local sum=$((num1 + num2))
echo "The sum is: $sum"
}
add_numbers 5 10 # 输出: The sum is: 15
注意事项
- 使用
local声明局部变量 - 默认通过标准输出返回结果
- 支持递归(注意深度限制)
- 使用
source或.导入函数库
七、local 关键字
声明函数内部的局部变量
示例
#!/bin/bash
global_var="Global variable"
my_function() {
local local_var="Local variable"
echo "Inside function: $global_var, $local_var"
}
my_function
echo "Outside function: $global_var"
# $local_var 在此不可访问
注意
- 只能在函数内部使用
- 变量作用域仅限于函数内
- 避免命名冲突,提高可维护性
八、return 命令
从函数返回状态码(0=成功,非0=错误)
与 exit 的区别
| 命令 | 作用域 | 效果 |
|---|---|---|
| return | 函数内部 | 仅退出当前函数 |
| exit | 脚本任意位置 | 退出整个脚本执行 |
示例
check_file_exists() {
local file_path="$1"
if [ -e "$file_path" ]; then
return 0 # 文件存在
else
return 1 # 文件不存在
fi
}
check_file_exists "/path/to/file"
if [ $? -eq 0 ]; then
echo "File exists"
else
echo "File not found"
fi