case…in分支语句
case…in分支语句的格式
1. 格式
case $变量名 in <====> switch ... case
常量表达式1) <====> case 常量表达式:
shell语句 <====> C语句
;; <====> break; 在shell中两个分号不可以省略
常量表达式2)
shell语句
;;
常量表达式3)
shell语句
;;
......
*) <====> default: 使用的是*通配符
shell语句
;;
esac
2. 常量表达式的书写格式
1> a) ----> 表示字符a
2> 2) ----> 表示数字2
3> a|b|c|d) ----> 表示a,d,c,d中的任意一个
4> [a-zA-Z]) ----> 表示,a-z和A-Z的任意一个
5> Y|y|yes|YES|Yes) ---> 表示Y|y|yes|YES|Yes字符串中的任意一个
6> [1-9]) ---> 数字1-9中的任意一个。
在case...in分支语句中,除了最后一个分支的两个分号可以省略,
其他分支的两个分号都不可以省略
case…in的练习题
1. 从终端输入一个字符,判断字符是数字,还是字符,还是标点符号。
#!/bin/bash
# your code
read -p "请输入一个字符 > " ch
case $ch in
[0-9])
echo "$ch 是一个数字"
;;
[a-zA-Z])
echo "$ch 是一个字母"
;;
\,|\.|\;|\?|\!)
echo "$ch 是一个标点符号"
;;
*)
echo "$ch 既不是数字,也不是字母,也不是标点符号"
;;
esac
2. 从终端输入成绩,判断成绩的等级,A,B,C,D,E。
#!/bin/bash
# your code
read -p "请输入你的成绩 > " score
if [ $score -lt 0 -o $score -gt 100 ]
then
echo "输入成绩不合理请重新输入"
exit
fi
level=$((score / 10))
case $level in
10|9)
echo "$score 成绩评定为 A"
;;
8)
echo "$score 成绩评定为 B"
;;
7)
echo "$score 成绩评定为 C"
;;
6)
echo "$score 成绩评定为 D"
;;
*)
echo "$score 成绩评定为 E"
;;
esac
3. 从终端输入年和月,判断是闰年还是平年,以及月份对应的天数。
#!/bin/bash
# your code
read -p "请输入年和月 > " year mouth
if [ $year -lt 0 ] ; then
echo "$year 不合理请重新输入"
exit
fi
if [ $mouth -lt 1 ] || [ $mouth -gt 12 ] ; then
echo "输入的月份不合理,请重新输入"
exit
fi
case $mouth in
1|3|5|7|8|10|12)
echo "$year年$mouth月共计有31天"
;;
4|6|9|11)
echo "$year年$mouth月共计有30天"
;;
2)
if ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0)) ; then
echo "$year年$mouth月共计有29天"
else
echo "$year年$mouth月共计有28天"
fi
esac
select…in选择分支语句
select…in语法格式
1. 格式
select 变量名 in 单词列表
do
shell语句
done
2. 注意事项
1> select...in语句是为了提高代码的交互性
2> 单词列表,就是多个以空格间隔的字符串,
当通过终端输入选择的编号,会从单词列表中选择对应的字符串赋值给“变量名”
select…in测试代码
#!/bin/bash
# your code
select num in ONE TWO THREE FOUR FIVE
do
echo "你的选择为$num"
done
linux@ubuntu:~/DC22101/day04$ bash 12select.sh --> 执行脚本文件,出现以单词列表目录
1) ONE
2) TWO
3) THREE
4) FOUR
5) FIVE
#? 1 ----> 输入目录对应的编号,只能输入编号,不可以输入目录名
你的选择为ONE
#? 4
你的选择为FOUR
#? 5
你的选择为FIVE
#? 6 ----> 如果输入没有的编号,默认为空
你的选择为
#? ----> 直接回车时,将目录再重新打印一次
1) ONE
2) TWO
3) THREE
4) FOUR
5) FIVE
#? ^C ----> ctrl + c 强制退出
select … in 经常和case…in语句配合使用。
#!/bin/bash
# your code
select os in Windows macOS Linux Android IOS
do
case $os in
"Windows")
echo "打开$os操作系统"
;;
"macOS")
echo "打开$os操作系统"
;;
"Linux")
echo "打开$os操作系统"
;;
"Android")
echo "打开$os操作系统"
;;
"IOS")
echo "打开$os操作系统"
;;
*)
echo "未知的操作系统"
;;
esac
done
while循环语句
while循环语句语法格式
1. 格式
while ((条件表达式))
do
shell语句
done
while [ 表达式 ] # while循环语句和test命令配合使用
do
shell语句
done
while [ true ] # 等价于C语言中的while(1){}死循环
do
shell语句
done
while循环语句案例
使用while循环完成0-100直接所有数的求和。
#!/bin/bash
# your code
sum=0
i=0;
while ((i <= 100))
do
((sum += i))
((i++))
done
echo "0-100之间的数求和 = $sum"
sum=0
i=0
while [ $i -le 100 ]
do
sum=`expr $sum + $i`
((i++))
done
echo "0-100之间的数求和 = $sum"
for循环语句
for循环的语法格式
1. 格式1:类似于C语言
for ((表达式1;表达式2;表达式3))
do
shell语句4
done
执行过程:[1,2][4,3,2][4,3,2][4,3,2]......
2. 格式2:类似于pythne语言
for 变量名 in 单词列表
do
shell语句
done
单词列表:多个单词以空格隔开的字符串
执行过程:依次将单词列表中的每个单词赋值给“变量名”,
执行单词列表中的所有的单词都依次赋值给“变量名”之后,循环结束
for循环参考案例
1. 使用for循环方式,依次遍历数组中的所有的成员。
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)
for (( i = 0; i < ${#arr[*]}; i++))
do
echo "arr[$i] = ${arr[$i]}"
done
echo "--------------------------------"
# 将数组的每个成员都在in后边展开,每循环1次从in后边取值赋值给
# 变量num,直到将in后边的所有值都进行取值之后,循环结束
i=0
for num in ${arr[@]}
do
echo "arr[$i] = $num"
((i++))
done
2. 使用for循环的嵌套打印以下图形
*
**
***
****
*****
…
#!/bin/bash
# your code
for ((i=0;i<5;i++))
do
for ((j=0;j<=i;j++))
do
# echo默认输出完成之后会打印一个换行符
# -n : 取消换行符
echo -n "*"
done
echo "" # 输出一个换行符
done
for i in 0 1 2 3 4
do
for ((j=0;j<=i;j++))
do
# echo默认输出完成之后会打印一个换行符
# -n : 取消换行符
echo -n "*"
done
echo "" # 输出一个换行符
done
# seq命令:按照某种个数输入一个等差数列
# seq 起始数字 间隔大小 结束数字 ---> 从起始数字到结束数字按照间隔输出对应的数字
# seq 起始数字 结束数字 ---> 从起始数字到结束数字按照默认间隔为1输出对应的数字
for i in `seq 1 5`
do
for j in `seq 1 $i`
do
# echo默认输出完成之后会打印一个换行符
# -n : 取消换行符
echo -n "*"
done
echo "" # 输出一个换行符
done
3. 定义一个数组,如下,使用冒泡排序的方式对以下数组进行排序
arr=(11 33 29 44 55 99 100 104 34 66)。
可以使用for (())的方式实现,可以使用for in的方式实现。
方式一:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)
echo "排序之前:${arr[*]}"
for ((i = 0; i < ${#arr[*]} - 1; i++))
do
for ((j = 0; j < ${#arr[*]} - $i - 1; j++))
do
if [ ${arr[j]} -gt ${arr[j+1]} ] ; then
tmp=${arr[j]}
arr[j]=${arr[j+1]}
arr[j+1]=$tmp
fi
done
done
echo "排序之后: ${arr[*]}"
方式二:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)
echo "排序之前:${arr[*]}"
x=`expr ${#arr[*]} - 2`
for i in `seq 0 $x`
do
y=`expr ${#arr[*]} - 2 - $i`
for j in `seq 0 $y`
do
if [ ${arr[j]} -gt ${arr[j+1]} ] ; then
tmp=${arr[j]}
arr[j]=${arr[j+1]}
arr[j+1]=$tmp
fi
done
done
echo "排序之后: ${arr[*]}"
方式三:
#!/bin/bash
# your code
arr=(11 33 29 44 55 99 100 104 34 66)
echo "排序之前:${arr[*]}"
for i in `seq 0 \`expr ${#arr[*]} - 2\``
do
for j in `seq 0 \`expr ${#arr[*]} - 2 - $i\``
do
if [ ${arr[j]} -gt ${arr[j+1]} ] ; then
tmp=${arr[j]}
arr[j]=${arr[j+1]}
arr[j+1]=$tmp
fi
done
done
echo "排序之后: ${arr[*]}"
break和continue
break格式
break n
1> break退出n层循环体,n大于等于1,如果n等于1,可以省略不写。
continue格式
continue n
1> continue退出n层本次循环,n大于等于1,如果n等于1,可以省略不写。
参考案例
#!/bin/bash
# your code
for i in `seq 0 5`
do
echo -n "#"
if [ $i -gt 3 ] ; then
break 1 # 退出循环体
fi
echo -n "*"
done
echo ""
for i in `seq 0 5`
do
echo -n "#"
if [ $i -gt 3 ] ; then
continue 1 # 退出本次循环
fi
echo -n "*"
done
echo ""
linux@ubuntu:~/DC22101/day04$ bash 17break.sh
#*#*#*#*#
#*#*#*#*##
shell中的函数
shell中函数定义
1. 格式:
function 函数名()
{
函数体
}
2. 注意事项
1> shell中定义的函数一般使用function进行修饰,但是也可以把function省略,
一般再shell中定义函数时不省略function关键字。
2> 再shell中定义的函数也要遵循先定义后似乎用的原则。
3> shell中的函数再小括号中不需要写形参列表,函数是否具有参数最终由书写函数时决定。
4> shell中的函数,函数名之前不需要写任何内容,表示函数是否具有返回值,
函数是否有返回值要根据自己定义的函数决定。
shell函数调用
函数没有形参:
函数名
函数具有形参:
函数名 实参列表(多个实参之间使用空格隔开)
在shell函数中获取获取调用函数传递的实参值
在shell函数中通过位置变量获取函数调用时传递的实参值
$0 ----> 不表示函数的名字,只表示执行脚本文件时,脚本文件的名字
$1
$2
.....
$n ---> 如果n>=10,则将n使用花括号括起来
$* ---> 所有的实参
$@ ---> 所有的实参
$# ---> 所有实参的个数和
函数的返回值
1. 通过全局变量返回
在shell的函数中定义的变量,默认也是全局的变量,
因此可以在函数外直接使用函数内定义的全局变量
2. 通过return返回
在shell中的函数通过return返回变量的值,只能返回0-255之间的数。
使用$?接收函数调用时,通过return返回的函数的值
3. 通过echo命令返回
在shell函数中调用echo命令返回,返回的返回值,可以返回任何值。
使用命令置换符接收函数通过echo返回的函数值。
变量名=`函数名 实参列表`
变量名=$(函数名 实参列表)
函数的参考案例
#!/bin/bash
# your code
# 1. 定义函数,函数没有参数,没有返回值
function print()
{
echo "hello world"
}
# 2. 定义函数,函数有参数,没有返回值
function show()
{
echo '$0='"$0"
echo '$1='"$1"
echo '$2='"$2"
echo '$3='"$3"
echo '$*='"$*"
echo '$@='"$@"
echo '$#='"$#"
}
# 3. 定义函数,函数有参数,有返回值,通过全局变量返回
function add_func1()
{
sum=0 # sum是一个全局变量,在函数外也可以访问
sum=$(($1 + $2))
}
# 4. 定义函数,函数有参数,有返回值,通过return返回,只能返回0-255之间的数
function add_func2()
{
local sum=0 # sum是一个局部变量
sum=$(($1 + $2))
return $sum
}
# 5. 定义函数,通过echo返回,
function add_func3()
{
local sum=0 # sum是一个局部变量
sum=$[$1 + $2]
echo $sum
}
# 1. 函数的调用
print
# 2. 函数的调用
show aa 11 ff
# 3. 调用函数
add_func1 100 200
# 访问add_func1函数中定义的全局变量
echo "add_func1(100,200) = $sum"
# 4. 函数的调用
add_func2 10 20 # 只能返回0-255之间的数,使用$?获取通过return返回的结果
echo "add_func2(10,20) = $?"
add_func2 100 200 # 只能返回0-255之间的数,结果为44
echo "add_func2(100,200) = $?"
# 5. 函数的调用, 通过命令置换符获取函数的返回结果
# 将函数的执行结果赋值给某个变量
sum3=`add_func3 1000 2000`
echo "add_func3(1000,2000) = $sum3"
练习题:通过终端输入用户名,通过/etc/passwd文件判断用户是否存在,
如果存在此用户获取用户名对应的uid
1> 输⼊⽤户的名字,判断该系统上是否存在该⽤户(封装为函数get_user_line(),若⽤户存在则返回用户名/etc/passwd中的⾏号)
提示:line=`grep "^输入的用户名" /etc/passwd -n | cut -d ":" -f 1`
2> 若存在该⽤户将这个⽤户名uid显示出来(封装为函数get_user_info(),将上述的函数返回的⾏号传递到这个函数中,返回uid)
提示:uid=`head -46 /etc/passwd | tail -1 | cut -d ":" -f 3`
#!/bin/bash
# your code
read -p "请输入用户名 > " userName
function get_user_line() {
local line=`grep "^$1" /etc/passwd -n | cut -d ":" -f 1`
return $line
}
function get_user_info() {
local uid=`head -$1 /etc/passwd | tail -1 | cut -d ":" -f 3`
echo $uid
}
get_user_line $userName
line=$?
echo $line
if [ $line -ne 0 ] ; then
echo "用户存在"
uid=`get_user_info $line`
echo $uid
else
echo "用户不存在"
fi
shell编程总结
1. 变量的定义
定义变量:变量名=初始值 变量名='初始值' 变量名="初始值"
引用变量:${变量名} 或 $变量名
位置变量:$n $* $# $@
2. 数组的定义
定义数组:数组名=(初始值列表,使用空格隔开)
数组成员访问:${数组名[index]} ${数组名[*]} ${数组名[@]}
${#数组名[*]} ${#数组名[@]} ${#数组名[index]}
修改成员或者添加成员:数组名[index]=新的值
3. 算数运算
(())
$[]
expr
4. 分支语句
if [ 表达式 ] ; then
else
fi
case $变量名 in
常量表达式)
;;
*)
;;
esac
select 变量名 in 单词列表(菜单选项列表)
do
done
5. 循环语句
while [ 表达式 ]
do
done
for 变量名 in 单词列表
do
done
6. break和continue
7. shell中的函数
函数定义 :
function 函数名()
{
}
函数调用:
函数名
函数名 实参表
函数中获取函数的实参:
$n ---> n >= 1
$*
$@
$#
函数的返回值:
函数中定义全局变量
return返回0-255直接的数,通过 $? 接收返回值
echo输出返回值,使用命令置换符获取函数的返回值