目录
一、流程控制
1、if else语句
if语法:
#多行
if 条件
then
命令
fi
#一行
if 条件; then 命令; fi
if-else语法:
if 条件 [ 条件判断式 ]
then
条件成立时,执行的命令
else
条件不成立时,执行的另一个命令
fi
if elif else语法:
if 条件1
then
当条件判断式1成立时,执行命令1
elif 条件2
then
当条件判断式2成立时,执行命令2
elif 条件3
then
当条件判断式3成立时,执行命令3
...
else
当所有条件都不成立时,最后执行该命令
fi
例子1(判断考试成绩):
[zhangjiajia@localhost ~]$ vim 3.sh
#!/bin/bash
read -p "请输入你的考试成绩:" score
if [[ score < 60 ]]
then
echo "不及格"
elif ((score>=60 && score<70))
then
echo "及格"
elif ((score>=70 && score<80))
then
echo "良好"
elif ((score>=80 && score<90))
then
echo "不错"
elif ((score>=90 && score<=100))
then
echo "优秀"
fi
输出结果为:
[zhangjiajia@localhost ~]$ sh 3.sh
请输入你的考试成绩:88
不错
例子2(数据写入指定文件):
[zhangjiajia@localhost ~]$ vim 4.sh
#!/bin/bash
read -p "请输入文件名:" filename
read -p "请输入数据:" data
if [[ -w $filename && -n data ]]
then
echo $data >> $filename
echo "文件写入成功"
else
echo "文件写入失败"
fi
输出结果如下:
[zhangjiajia@localhost ~]$ sh 4.sh
请输入文件名:2.txt
请输入数据:123
文件写入成功
2、case语句
介绍:
case语句为多选择语句,可以用case语句匹配一个值与一个模式,匹配成功则执行相匹配的命令。通常用于分支多,且判断条件简单的情况下。
注意:
case语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行 “*)”
(*代表所有其他值)的程序。
case语句以“case”开头,以“esac”结尾。
每一个分支程序之后要通过“;;”双分号结尾,代表该程序段结束(千万不要忘记,每次写case语句,都不要忘记双分号)。
基本语法:
case 值 in
匹配模式1)
命令1
命令2
...
;;
"值2")
匹配模式2)
命令1
命令2
...
;;
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
case语句支持正则表达式,只不过使用的表达式较为简单。
简单的正则表达式支持如下通配符:
格式 | 说明 |
---|---|
* | 表示任意的字符串。 |
[abc] | 表示 a、b、C三个字符中的任意一个。比如,[ 15ZH ] 表示1、5、Z、H四个字符中的任意一个。 |
[m-n]| | 表示从m到n的任意一个字符。比如,[0-9]表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| | 表示多重选择,类似逻辑运算符中的或运算。比如,abc | xyz 表示匹配字符串"abc"或者"xyz"。 |
例子(输入数字判断星期):
[zhangjiajia@localhost ~]$ vim 5.sh
#!/bin/bash
read -p "请输如一个0-7的数字:" score
case $score in
1)
echo "星期一"
;;
2)
echo "星期二"
;;
3)
echo "星期三"
;;
4)
echo "星期四"
;;
5)
echo "星期五"
;;
6)
echo "星期六"
;;
7|0)
echo "星期日"
;;
*)
echo "错误,请重新输入"
;;
esac
输出结果如下:
[zhangjiajia@localhost ~]$ sh 5.sh
请输如一个0-7的数字:1
星期一
[zhangjiajia@localhost ~]$ sh 5.sh
请输如一个0-7的数字:0
星期日
[zhangjiajia@localhost ~]$ sh 5.sh
请输如一个0-7的数字:7
星期日
[zhangjiajia@localhost ~]$ sh 5.sh
请输如一个0-7的数字:9
错误,请重新输入
3、while循环
介绍:
在while循环中,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。
语法:
#多行
while 条件
do
命令1
命令2
...
continue; #结束本次循环,进入下一次
break; #结束当前循环
done
#一行
while 条件; do 命令; done;
例子:
[zhangjiajia@localhost ~]$ vim 6.sh
#!/bin/bash
read -p "请输入一个数字:" score
i=1
while true
do
if ((i > score))
then
echo "循环结束"
break;
fi
echo "Hello"
((i=i+1)) #或者let i++
done
输出结果为:
[zhangjiajia@localhost ~]$ sh 6.sh
请输入一个数字:4
Hello
Hello
Hello
Hello
4、for循环
介绍:for循环是固定循环,也就是在循环时已经知道需要进行几次的循环,有时也把for循环称为计数循环。for的语法有如下三种:
语法:
语法1:
for var in item1 item2 ... itemN
do
命令1
命令2
...
done
#var是循环变量
#item1 item2...itemN为循环范围
语法2:
for var in {start..end}
do
命令1
命令2
...
done
语法3:
for((i=start;i<=end;i++))
do
命令1
命令2
...
done
循环跳出语句介绍:
continue语句:跳出本次循环、还会进入到下一次循环。
break语句:跳出当前循环、循环结束。
当程序执行到break语句时,会结束整个当前循环。而continue 语句也是结束循环的语句,不过continue 语句是指结束本次循环,而下次循环会继续。
例子1:
[zhangjiajia@localhost ~]$ vim 7.sh
#!/bin/bash
read -p "请输入一个数字:" score
i=1
for i in 1 3 5 #第1、第3、第5
#也可以{1..5}
do
if [[ i > score ]]
then
echo "循环结束"
break;
fi
echo "Hello${i}"
((i=i+1)) #或者let i++
done
输出结果如下:
[zhangjiajia@localhost ~]$ sh 7.sh
请输入一个数字:5
Hello1
Hello3
Hello5
例子2:
[zhangjiajia@localhost ~]$ vim 9.sh
#!/bin/bash
read -p "请输入一个数字:" score
for((i=1;i<=$score;i++))
do
echo "Hello${i}"
done
输出结果如下:
[zhangjiajia@localhost ~]$ sh 9.sh
请输入一个数字:9
Hello1
Hello2
Hello3
Hello4
Hello5
Hello6
Hello7
Hello8
Hello9
5、until循环
介绍:
until循环与while循环等循环语句相反,while循环是条件语句为true则一直循环、until循环是条件语句判断为true则停止、判断为false则一直循环。
语法:
until 条件
do
命令
done
例子(计算出1~输入数字至今实有数的和):
[zhangjiajia@localhost ~]$ vim
#!/bin/bash
read -p "请输入一个大于0的数字" number
i=1
sum=0
until (( $i >$number ))
do
sum=$(($sum+$i))
let i++
done
echo "和为:${sum}"
11.sh
输出结果如下:
[zhangjiajia@localhost ~]$ sh 11.sh
请输入一个大于0的数字100
和为:5050
6、select语句
介绍:
select in 循环用来增强交互性,可以显示出带编号的菜单、用户根据不同的编号可以选择不同的菜单,并执行该功能。
语法:
select var in menu1 menu2 ... menuN
do
命令
done
例子(判断爱好并做出回应):
[zhangjiajia@localhost ~]$ vim 10.sh
echo "您的爱好是:${score}"
select score in "打球" "游戏" "编程"
do
#echo "$score"
#break;
case $score in
"打球")
echo "运动有益身体健康"
break;
;;
"游戏")
echo "游戏更有益身体健康"
break;
;;
"编程")
echo "编程有害身体健康"
break;
;;
*)
echo "重新输入"
esac
done
echo "您的爱好是:${score}"
输出结果如下:
[zhangjiajia@localhost ~]$ sh 10.sh
您的爱好是:
1) 打球
2) 游戏
3) 编程
#? 3
编程有害身体健康
您的爱好是:编程
二、函数
介绍:
shell与其他编程语言一样,有函数,目的是为了实现Shell脚本代码重用和模块化编程。
分类:
分为系统函数和自定义函数。
1、系统函数
介绍:
系统自带的函数,可以直接使用
1.basename系统函数:
作用:
用于获取文件名的函数,根据给出的文件路径截取出文件名
语法:
basename [ string / pathname ] [ suffix ]
#suffix:用于截取的时候去掉指定的后缀名
演示:
[zhangjiajia@localhost ~]$ basename /home/zhangjiajia/read1.sh
read1.sh
[zhangjiajia@localhost ~]$ basename /home/zhangjiajia/read1.sh .sh
read1
2.dirname系统函数
作用:
从指定的文件绝对路径,去除文件名,返回剩下的前缀目录路径。
语法:
dirname 文件绝对路径
演示:
[zhangjiajia@localhost ~]$ dirname /home/zhangjiajia/read1.sh
/home/zhangjiajia
2、自定义函数
介绍:
开发人员可以通过自定义开发函数,实现代码重用。
注:
可以带function fun()定义,也可以直接fun()定义,不带任何参数
参数返回,可以使用return语句返回值,也可以不使用。如果不使用,则以最后一条命令运行结果,作为返回值。
1.无带参数:
函数基本语法:
#函数的定义
[ function ] funname ()
{
命令
[ return 返回值 ]
}
#调用函数
funname 传递函数1 传递函数2 .... 传递函数N
#必须先定义函数再调用
例子(输入两个数字、并求和):
[zhangjiajia@localhost ~]$ vim fun1.sh
#!/bin/bash
sum()
{
read -p "请输入第一个数字:" a
read -p "请输入第二个数字:" b
echo "执行函数"
echo "两个数字分别为:${a} 和 ${b}"
return $(($a+$b))
}
sum
echo "两个数字的和为: $?"
运行结果如下:
[zhangjiajia@localhost ~]$ sh fun1.sh
请输入第一个数字:3
请输入第二个数字:4
执行函数
两个数字分别为:3 和 4
两个数字的和为: 7
2.有参函数
介绍:
在Shell中,调用函数时可以向其传递参数,在函数体内部,通过$n 的形式来获取参数的值,例如:$1为第一个参数、$2为第二个、以此类推
其他参数介绍:
参数处理 | 说明 |
---|---|
$# | 传递到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数 |
$? | 显示最后命令的退出状态,0表示没有错误,其他的值表示有错误 |
演示:
[zhangjiajia@localhost ~]$ vim fun2.sh
#!/bin/bash
funParam(){
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第十个参数为:${10}"
echo "参数总数为:$# 个"
echo "获取所有参数、以一个字符串返回: $*"
}
funParam
funParam 1 2 3 4 5 6 7 8 00 76 4 5 7 354
运行结果如下:
[zhangjiajia@localhost ~]$ sh fun2.sh
第一个参数为:
第二个参数为:
第十个参数为:
参数总数为:0 个
获取所有参数、以一个字符串返回:
第一个参数为:1
第二个参数为:2
第十个参数为:76
参数总数为:14 个
获取所有参数、以一个字符串返回: 1 2 3 4 5 6 7 8 00 76 4 5 7 354
3.shell程序与函数的区别
区别:
两者比较相似,区别在于:
Shell程序(内置命令和外部脚本文件),外部脚本文件是在子shell中运行,会开启独立的进程运行,shell函数是在当前shell的进程中运行
注:
Shell程序命令:运行时开启一个子进程运行命令
函数:在当前shell环境中运行,没有开启进程
演示:
[zhangjiajia@localhost ~]$ vim fun3.sh
#!/bin/bash
funID(){
echo "当前函数进程ID号:$$"
}
echo "打印当前脚本文件进程:$$"
funID
结果如下:
[zhangjiajia@localhost ~]$ sh fun3.sh
打印当前脚本文件进程:24386
当前函数进程ID号:24386
[zhangjiajia@localhost ~]$ echo $$
2662
三、重定向输入输出
重定向语法:
命令 | 说明 |
---|---|
命令> file | 将正确数据重定向输出到file 文件中,覆盖方式 |
命令< file | 将输入重定向从file文件中读取数据 |
命令>> file | 将正确数据重定向输出到file文件中,追加方式 |
命令< file1 > file2 | 从file文件读取数据,输出数据到file2文件中 |
命令fd> file | 根据指定的文件描述符fd将数据重定向输出到file文件中,覆盖方式 |
命令fd>> file | 根据指定的文件描述符fd将数据重定向输出到file文件中,追加方式 |
命令> file fd1>& fd2 | 将fd1和fd2文件描述符合并从文件读取输入. |
fd1<& fd2 | 将fd1和fd2文件描述符合并从文件读取输入. |
<< tag | 读取终端输入数据,将开始标记tag和结束标记tag之间的内容作为输入。标记名tag可以任意 |
注意:>为覆盖(原有数据会被删除),>>为追加(加在原有的数据后面)
fd是文件描述符:
0通常是标准输入
1是标准输出
2是标准错误输出
演示 :
[zhangjiajia@localhost ~]$ i=0;while read str;do echo "第${i}行:$str";let i++;done < 2.txt
第0行:14567+3456
第1行:12345*3456/453
第2行:76345.1432+4567345324/3246567
第3行:123
[zhangjiajia@localhost ~]$ wc -l << EOF
> 123
> 123
> 123543
> 435645
> 23342
> 4564
> 1234
>
> quit
> EOF
9