目录
1.实现一个对数组求和的函数,数组通过实参传递给函数
结果为:
2.写一个函数,输出当前用户的uid和id,并使用变量接收结果
结果为:
shell脚本指令前七个网页链接:
八、shell中的分支语句
【1】if···else分支
【2】test指令
1、创建一个文件,给组用户可读权限,所属用户可写权限,其他用户可执行权限,使用if判断文件有哪些权限
2、终端输入年份,判断闰平年(四年一闰,百年不闰,四百年再闰)
3、终端输入一个.sh文件名,判断文件是否存在,如果存在判断文件是否有可执行权限,如果有执行脚本,如果没有添加可执行权限,如果文件不存在,创建脚本文件
4、终端输入一个.c文件名,判断文件中是否有内容,如果有内容编译该文件,如果没有内容删除文件
5、终端输入两个文件名,判断文件的时间戳哪一个更新
【3】case···in语句
1、终端输入学生成绩,判断等级100-90A,90-80B,80-70C,70-60D,其他不及格
2、终端输入一个字符,判断是字母还是数字字符
3、终端输入年,月,判断该月有多少天,1-12以外的月份,输入不合理
总结:
九、循环语句
【1】while
1、求1-100的和,5050
2、终端输入数组,使用while循环,实现数组中元素的求和
3、终端输入行数,打印直角三角形
【2】for
1、求100-1000内的水仙花数,(个位^3+十位^3+百位^3=数本身)
2、定义一个稀疏数组,求数组中元素的和
3、求家目录下目录文件和普通文件个数的和
使用连续列表的情况
【3】select···in
【4】select···in和case···in结合
1、终端输入一个游戏名,让用户选择是否下载,如果用户选择的是Y|YES|y|yes就下载该游戏,N|NO|n|no就不下载该游戏。
十、辅助控制关键字
【1】break
十一、函数
【1】定义
【2】函数的调用
【3】函数如何获取外部参数
【4】获取函数的返回值
【5】没有返回值的函数怎么接收结果
【6】local在函数中的使用
#!/bin/bash
function sumarr()
{
sum=0
arr=($*)
for i in ${arr[*]}
do
((sum+=i))
done
echo "数组的和为:"$sum
}
sumarr 100 100 10 20 30 40
#!/bin/bash
function getuidgid()
{
uid=`id -u`
gid=`id -g`
echo "uid为:$uid"
echo "gid为:$gid"
}
ugid=`getuidgid`
echo $ugid
https://blog.csdn.net/ck0056/article/details/132745232
[]就是test指令
#单分支结构
if [ test语句 ] -----> if test 表达式
then
语句块
fi
#双分支
if [ test语句 ] -----> if test 表达式
then
语句块
else
条件不成立执行的语句块
fi
#多分支语句
if [ test语句 ] -----> if test 表达式
then
语句块
elif [ test语句 ] ------> elif test 表达式
then
条件不成立执行的语句块
fi
#!/bin/bash
num1=90
num2=300
#if [ $num1 -le $num2 ]
if test $num1 -le $num2
then
echo "num1<=num2"
fi
test是一个终端指令,用于条件判断
man test
字符串:------>test对于字符串的判断,需要给字符串加""
string1 = string2:判断字符串1和字符串2是否相等
string1 != string2:判断字符串1和字符串2是否不相等
-n string1:判断字符串1不为空
-z string1:判断字符串1为空
整形数据的判断:
-eq:两个数相等
-ne:两个数不相等
-gt:第一个大于第二个数
-ge:第一个数大于等于第二个数
-lt:第一个数小于第二个数
-le:第一个数小于等于第二个数
文件相关的操作:
file1 -nt file2:1的时间戳比2更新
file1 -ot file2:1的时间戳比2更旧
file1 -ef file2:1和2有相同的inode号
-b:文件存在且为块设备文件
-c:文件存在且为字符设备文件
-L/-h:文件存在且为软链接文件
-S:文件存在且为套接字文件
-s:文件存在且有内容
-e:文件存在
-f:文件存在且为普通文件
-r:存在且有可读权限
-w:文件存在且有可写权限
-x:文件存在且有可执行权限
#!/bin/bash
touch 1
chmod 241 1
if [ -r 1 ]
then
echo "文件1有可读权限"
fi
if [ -w 1 ]
then
echo "文件1有可写权限"
fi
if [ -x 1 ]
then
echo "文件1有可可执行权限"
fi
#!/bin/bash
read -p "请输入一个年份" year
#对年份的判断
#year对4\100和400取余都是算术运算,需要借助于(())\$[]\let\expr
#test指令内不能使用&&和||进行运算,test提供了-a进行逻辑与,-o进行逻辑或
if [ $((year%4)) -eq 0 -a $((year%100)) -ne 0 -o $((year%400)) -eq 0 ]
#if [ $((year%4)) -eq 0 ] && [ $((year%100)) -ne 0 ] || [ $((year%400)) -eq 0 ]
#if [ $((year%4==0&&year%100!=0||year%400==0)) -eq 1 ]
then
echo "$year是一个闰年"
else
echo "$year不是一个闰年"
fi
#!/bin/bash
read -p "请输入.sh文件" var
if [ -e "$var" ]
then
echo "文件存在"
if [ -x "$var" ]
then
bash $var
else
chmod 777 $var
fi
else
echo"文件不存在"
touch $var
fi
#!/bin/bash
read -p "请输入一个.c文件" filename
if [ -s $filename ] #判断文件是否存在且有内容
then
gcc $filename
else
if [ -e $filename ] #如果文件存在
then
rm $filename
echo "$filename已删除"
else
echo "$filename不存在"
fi
fi
#!/bin/bash
read -p "请输入两个文件名" filename1 filename2
if [ $filename1 -nt $filename2 ]
#如果条件成立,-nt参数表示前面文件的时间戳更新
then
echo "$filename1更新"
else
echo "$filename2更新"
fi
case $变量名 in
常量1)
语句
;; ------->类似于C中break的作用,;;除了最后一条分之外,都不能省略
常量2)
语句
;;
····
常量n)
语句
;;
*) ------->类似于C中default,但是*表示通配所有情况,只能放在最后
语句
esac
case···in中常量可能的形式:
1|2|3|4):满足1,2,3,4中任一个即可
[0-9]):满足0-9中任一个
[0-3]|4):满足0-3和4中的任一个
#!/bin/bash
read -p "请输入成绩" score
ret=$((score/10))
: 'case $score in
1??|9?)
echo "A"
;;
8?)
echo "B"
;;
7?)
echo "C"
;;
6?)
echo "D"
;;
*)
echo "不及格"
esac'
case $ret in
10|9)
echo "A"
;;
8)
echo B
;;
7)
echo C
;;
6)
echo D
;;
*)
echo "不及格"
esac
read -p "请输入一个字符" var
case $var in
[0-9])
echo "是一个数字"
;;
[A-Z]|[a-z])
echo "是一个字母"
;;
*)
echo 不是数字也不是字母
esac
- case···in语句,判断变量的值,$变量名
- 在shell中;;不能不写,最后一个分支可以不写
- *通配所有情况,如果想使用*表示其他分支的情况,不能把*放在上面
while [ test语句 ] ------>while test 表达式
do
循环体
done
#!/bin/bash
i=0
while [ $i -lt 5 ]
do
echo hello world
((i++))
done
#!/bin/bash
read -p "请输入行数" line
i=1
j=1
while [ $i -le $line ]
do
j=1 #每一次进入内层循环前j都从1开始
while [ $j -le $i ]
do
echo -n "*"
((j++))
done
echo "" #每行输出结束需要换行
((i++))
done
第一种:类似于C的格式
for ((表达式1;表达式2;表达式3))
do
循环体
done
第二种:shell中的格式
for 变量名 in 字符串列表
do
循环体
done
for i in aa bb cc dd
do
echo $i
done
执行逻辑:
让变量循环遍历,字符串列表中的每一种情况,遍历结束后结束循环,
循环的次数和字符串列表中字符串的个数有关
#!/bin/bash
#for i in `seq 100 999`
for i in {100..999} #{1..3}展开1-3内的每一个数
do
x=$((i%10)) #求个位
y=$((i/10%10)) #求十位
z=$((i/100)) #求百位
if [ $((x**3+y**3+z**3)) -eq $i ]
then
echo $i是一个水仙花数
fi
done
arr=([0]=12 [5]=78 [7]=23)
sum=0
for j in ${arr[*]}
do
((sum+=j))
done
echo $sum
#!/bin/bash
fnum=0
dnum=0
for i in `ls ~`
do
if [ -d ~/$i ]
then
((dnum++))
fi
if [ -f ~/$i ]
then
((fnum++))
fi
done
echo $((dnum+fnum))
#!/bin/bash
#var1和var2都是软连接文件
var1=2
var2=test1
#对软连接文件判断是,实际是在判断源文件
if [ -f $var1 ]
then
echo "$var1是一个普通文件"
fi
if [ -d $var2 ]
then
echo "$var2是一个目录文件"
fi
1、seq 起始值 间隔值 终止值 ---->在终端回显,起始到终止值间的连续序列
seq 1 1 100 --->输出1-100
seq 如果后面只有一个数,默认是终止值,起始值和间隔值默认为1
拿到seq的结果需要使用命令置换符
`seq 1 1 100`
2、{1..3} ---->展开1-3内的每一个数,中间是两个.不能多写
select 变量名 in 选项列表
do
语句块
done
执行逻辑:
会在终端打印选项列表,让用户选择,用户选择是需要选择对应的序号,
如果用户不输入直接回车,会再打印一次选项列表,
如果选择错误,变量就获取到空值
#!/bin/bash
select i in aa bb cc dd
do
echo $i
done
运行的结果
1) aa
2) bb
3) cc
4) dd
#?
如果想要退出select···in语句,直接使用ctrl+c
#!/bin/bash
#select```in和case ```in结合
#可以通过用户的不同选择执行不同的指令
select i in linux wins macos q Q
do
case $i in
linux)
echo "打开的是Linux系统"
;;
wins)
echo "打开的是wins系统"
;;
macos)
echo "打开的是macos系统"
;;
q)
break
;;
Q)
exit
;;
*)
echo "选择错误"
esac
done
echo hello world
#!/bin/bash
read -p "请输入游戏名" gname
select i in Y YES y yes N NO n NO
do
case $i in
Y|YES|y|yes)
echo "下载$gname"
;;
N|NO|n|no)
echo "不下载$gname"
exit
esac
done
C中:退出本层循环
continue n ------->退出n层本次循环
continue 1 ------->1可以不写
#!/bin/bash
for((i=1;i<3;i++))
do
echo "进入第一层循环 i=$i*******************"
echo
for j in `seq 1 1 2`
do
echo "进入第二层循环 j=$j------------------"
echo
for k in {1..3}
do
echo "进入第三层循环 k=$k /"
echo
if [ $k -eq 2 ]
then
echo "准备跳出循环"
#break 3
continue 3
fi
echo "退出第三层循环 k=$k/"
echo
done
echo "退出第二层循环 j=$j------------------"
echo
done
echo "退出第一层循环 i=$i*******************"
echo
done
shell中:
function 函数名()
{
函数体
return 返回值(如果实现函数时有返回值就写return)
}
shell中函数的注意事项:
1、function在定义函数时,可以加也可以不加(建议加)
2、()内不能添加任何内容,函数是否有参数根据调用来决定
3、如果函数有返回值,直接在函数的定义中写出return
4、shell中的函数仍然满足先定义后调用的原则,shell中函数的定义和声明不能分开
函数名 实参1 实参2 实参3 ···· (函数有参数的情况)
函数名 (没有参数)
仍然通过位置变量获取 ${n}
脚本的外部传参和函数的外部传参互不干扰:
如果在函数中使用位置变量获取到的就是函数的外部参数,
如果在脚本中使用位置变量获取到的就是脚本的外部参数,$0只能获取脚本名
$? 获取函数的返回值 ----->使用$?的上一条指令一定是函数的调用
$?的本质是获取到上一条指令的执行结果,
#!/bin/bash
function fun()
{
echo hello world
}
function add()
{
echo $(($1+$2))
echo $0
a=258
return $a #返回值只能返回0-255之中的数
}
add 12 34
var=$? #使用$?接收函数的返回值
echo $var
echo $a
如果函数没有返回值,但是有输出语句,可以使用命令置换符接收
#!/bin/bash
function fun()
{
echo hello world
}
a=90
function add()
{
#echo $(($1+$2))
#echo $0
a=258
return $a #返回值只能返回0-255之中的数
}
: 'add 12 34
var=$? #使用$?接收函数的返回值
echo $var
echo $a #可以访问a的值,a是一个全局变量
'
#如何接受fun函数的结果
ret=`fun`
echo $ret #代码只有1行输出,fun中的输出已经被命令置换符接收了
add
echo $a #258,因为a在函数内被改变了
#!/bin/bash
function fun()
{
echo hello world
}
a=90
function add()
{
#echo $(($1+$2))
#echo $0
a=258
local b=80 #被定义成了一个局部变量
echo $b
unset b #unset是可以清空局部变量
echo $b
return $a #返回值只能返回0-255之中的数
}
: 'add 12 34
var=$? #使用$?接收函数的返回值
echo $var
echo $a #可以访问a的值,a是一个全局变量
'
#如何接受fun函数的结果
ret=`fun`
echo $ret #代码只有1行输出,fun中的输出已经被命令置换符接收了
add
echo $a #258,因为a在函数内被改变了
echo $b #空行,因为b在函数内是一个loacl类型的变量,局部变量