学习视频泷羽sec:shell编程(8) until循环以及函数基本创建调用_哔哩哔哩_bilibili
一、until 循环
until
循环的语法类似于 while
循环,但它的条件是 当条件为假时,循环会继续执行。可以理解为 while
循环的条件是 为真时,而 until
则相反,条件为假时执行。
语法:
until [ 条件 ]
do
# 循环体
done
例子:
#!/bin/bash
count=1
until [ $count -gt 10 ] # 直到 count 大于 5 时退出
do
echo "Count is: $count"
((count++)) # 增加 count
done
1.代码功能概述
-
until
循环:只有在循环条件为 真 时才退出。这里的条件是count -gt 10
,当count
达到 11 时,条件成立,循环停止。 -
通过
count++
,每次循环结束后,count
会递增 1,直到达到退出条件。
2.循环条件分析
-
until [ $count -gt 10 ]
:-
until
循环会一直执行,直到指定的条件为 真。 -
在这个例子中,条件是
[ $count -gt 10 ]
,表示当count
大于 10 时,条件为真。 -
只有当
count
大于 10 时,until
循环才会停止执行。
-
3.执行过程
-
初始时,
count=1
。 -
循环开始时,检查条件
[ $count -gt 10 ]
。由于count
初始为 1,条件1 -gt 10
为假,因此继续执行循环体。 -
输出当前
count
的值:Count is: 1
。 -
然后
count
增加 1,count
变为 2。 -
再次检查条件
[ $count -gt 10 ]
,此时count
为 2,条件2 -gt 10
仍为假,继续执行循环。 -
依此类推,直到
count
增加到 11。 -
当
count
为11 时,检查条件[ $count -gt 10 ]
,此时条件为真,循环退出。
二、case 语句
case
语句用于多重条件匹配,它根据变量的值与多个模式进行比较,执行匹配成功的块,类似于其他语言中的 switch
语句。
语法:
case "$变量" in
模式1)# 当变量匹配模式1时执行
;;
模式2)# 当变量匹配模式2时执行
;;
*)# 默认情况
;;
esac
例子:
#!/bin/bash
read -p "请输入一个数字:" num
case $num in
1)echo "你输入的是数字 1"
;;
2)echo "你输入的是数字 2"
;;
3)echo "你输入的是数字 3"
;;
*)echo "输入的数字不在预期范围内"
;;
esac
1.代码功能概述
该脚本使用 case
语句根据用户输入的数字输出不同的提示信息。用户输入的数字将与预设的 1
、2
、3
进行匹配。如果输入的数字是其中之一,则输出相应的消息;如果输入的数字不在预期的范围内(即不等于 1
、2
、3
),则输出默认的提示消息。
2.循环条件分析
虽然这段脚本中没有使用显式的 循环(例如 for
或 while
循环),但它依然有条件判断逻辑。具体来说,case
语句会根据用户输入的数字值执行不同的分支,类似于条件分支的“匹配”过程。
具体流程:
-
用户通过
read -p
提示输入一个数字,将该数字存储在变量num
中。 -
case语句根据num的值执行以下匹配:
-
如果用户输入的是
1
,输出"你输入的是数字 1"
。 -
如果用户输入的是
2
,输出"你输入的是数字 2"
。 -
如果用户输入的是
3
,输出"你输入的是数字 3"
。 -
如果用户输入的是其他数字或字符(与预设的
1
、2
、3
都不匹配),则会执行默认分支,输出"输入的数字不在预期范围内"
。
-
三、shell脚本的函数
在Shell脚本中,函数(function)是用来组织和封装代码块的一种方式,它能够帮助你提高代码的可读性和可重用性。我们可以将多次需要执行的命令、语句块或逻辑封装成一个函数,调用时只需提供函数名,Shell会自动执行对应的代码。
-
Shell函数的参数可以通过
$1
,$2
,$@
,$#
等方式访问。 -
使用
local
关键字定义局部变量,避免变量污染。 -
函数的返回值通常通过
echo
输出,而return
语句通常用于返回状态码。 -
使用
shift
可以处理函数中的多参数,递归也可以在Shell函数中实现。
1. 函数的定义与使用
在Shell脚本中,函数是通过 function
关键字或直接使用函数名来定义的。可以通过 ()
定义函数,也可以通过 return
语句返回函数的结果。
语法:
# 定义函数
function my_function {
# 函数体
}
# 或者可以直接使用下面的方式
my_function() {
# 函数体
}
两者是等价的,选择哪种方式主要取决于个人或团队的代码风格。传统方式比较简洁,而带 function
关键字的方式可能显得更直观,特别是当函数非常复杂时。
例子:
#!/bin/bash
# 定义一个简单的函数
greet() {
echo "Hello, $1!" # $1 是传入的第一个参数
}
# 调用函数
greet "tom"
greet "你见过龙吗?"
2. 函数的传参
Shell函数可以接收外部传递的参数,函数的参数是通过 $1
、$2
、$3
、$0
、$@
、$#
等位置变量来访问的,这些变量代表了传递给函数的参数。
-
$1
,$2
,$3
:分别代表了传入参数的第一个、第二个、第三个位置。 -
$0
:表示脚本本身的名称。
-
$@
:表示传递给函数的所有参数,作为一个单独的字符串数组来处理。 -
$#
:表示传递给函数的参数个数。
例子:
#!/bin/bash
# 定义一个函数,计算两个数的和
sum() {
local num1=$1 # 第一个参数
local num2=$2 # 第二个参数
echo "Sum is: $((num1 + num2))"
}
# 调用函数,传递两个参数
sum 5 7
sum 10 20
3. 局部变量(local
)
在Shell脚本中,默认情况下,所有变量的作用范围是全局的,这意味着如果在一个函数内部修改了一个变量的值,它将影响到函数外部的相同变量。如果我们想在函数内部定义一个仅在该函数范围内有效的变量,可以使用 local
关键字。
#!/bin/bash
my_function() {
local var="local_variable"
echo "Inside function: $var"
}
# 在函数外部访问同名变量
var="global_variable"
my_function
echo "Outside function: $var"
可以看到,local
关键字确保了 var
变量仅在 my_function
内部有效,函数外部的 var
变量没有受到影响。
为什么使用 local
?
-
避免命名冲突:当一个脚本中有多个函数时,如果多个函数使用相同的变量名而没有使用
local
,它们可能会相互覆盖,造成意外的结果。使用local
可以有效避免这种情况。 -
封装性:使用
local
可以将变量的作用域限制在函数内部,提升代码的可维护性和可读性。
4. 函数返回值
Shell函数默认没有返回值,但你可以使用 return
语句返回一个整数值。需要注意的是,return
语句只能返回 0 到 255 之间的整数(通常用于表示状态码)。
例子:
#!/bin/bash
# 定义一个函数,检查文件是否存在
check_file() {
if [ -f "$1" ]; then
return 0 # 文件存在
else
return 1 # 文件不存在
fi
}
# 调用函数并检查返回值
check_file "/etc/passwd"
if [ $? -eq 0 ]; then
echo "文件存在"
else
echo "文件不存在"
fi
5. 函数中的递归调用
Shell支持函数的递归调用,也就是函数在自身内部调用自身。递归调用通常需要一个基准条件来防止无限递归。
递归示例:计算阶乘
#!/bin/bash
factorial() {
if [ $1 -le 1 ]; then
echo 1
else
local result=$(( $1 * $(factorial $(( $1 - 1 )) ) ))
echo $result
fi
}
result=$(factorial 5)
echo "Factorial of 5 is: $result"
6. 内建函数与外部函数的区别
-
内建函数:Shell本身内置的命令和函数(例如
echo
,read
,test
,pwd
等),这些函数不需要额外定义,Shell会直接识别。 -
外部函数:通过 Shell 脚本或程序中定义的函数。这些函数是用户自定义的,不是Shell内建的。
本章总结
-
until
循环:我们学习了until
循环的语法和工作原理。它会在循环条件为false
时继续执行,直到条件变为true
,常用于需要在特定条件下反复执行命令的场景。 -
case
语句:通过case
语句,我们可以根据多个条件的不同值执行不同的代码块。它是 Shell 脚本中实现多分支选择的有效方式,比起多个if-else
判断,case
提供了更加清晰和简洁的结构。 -
Shell 脚本函数:函数的引入使得脚本更加模块化,方便复用。我们学习了如何定义函数、如何传递参数、如何使用局部变量 (
local
),以及如何避免全局变量的干扰。local
变量可以有效地封装函数内部的状态,避免与外部变量冲突,提高脚本的稳定性和可维护性。 -
函数的返回值:在 Shell 中,函数通过
echo
输出值或通过return
返回退出状态码来传递结果。我们讨论了如何处理这些返回值,并通过实例理解了函数如何与脚本中的其他部分交互。 -
递归调用:递归是函数在自身内调用自身的一种方法。我们通过计算阶乘的示例展示了递归如何在 Shell 脚本中实现,并理解了基准条件的重要性。
-
内建函数与外部函数的区别:内建函数是 Shell 自带的命令或功能,不需要额外定义;而外部函数是我们自定义的函数,提供了更灵活的功能扩展。
通过掌握这些技巧,我们不仅能够编写更清晰、更高效的脚本,还能够应对复杂的编程任务。理解并灵活运用 Shell 的控制结构、函数和递归,将大大提升我们的脚本编写能力,进而在自动化和系统管理中达到更高的效率。