目录
1.shell编程的基本格式
开头
注释
加可执行权限
执行脚本的三种方法
2.变量
定义变量和清除变量
从键盘获取值(read)
读取多个值
只读变量(readonly)
位置变量
变量运算
3.条件测试
文件测试
字符串测试
数值测试
逻辑操作符
4. if条件语句
if条件语句语法
单分支if语句
多分支语句
5. case条件语句
case语句的语法
case语句实践
6.for循环语句
语法格式
for循环显示当前目录下的文件
for循环打印99乘法表
7.while循环和until循环
while循环语法
while循环示例
until循环语法
until循环示例
8.break,continue和exit
break示例
continue示例
exit示例
9.函数
定义函数的格式
调用函数格式
案例演示
函数中的return
函数案例
统计路径下文件数目
shell脚本之猜数字游戏
1.shell编程的基本格式
开头
shell脚本通常以 #!/bin/bash 或 #!/bin/sh 开头,如下面这个最简单的shell脚本。
#!/bin/bash
echo "hello world"
通常最开始定义的是该脚本的解释器,即该脚本由什么shell来解释
注释
单个的 # 为注释当前行的内容。
加可执行权限
可以看到,当给hello.sh文件加上可执行权限后,其颜色也会发生变化。
执行脚本的三种方法
1. ./xxx.sh---------------按照文件中指定的解释器解析,并且这种方式需要文件有可执行权限
2. bash xxx.sh---------指定bash解释器解析
3. . xxx.sh---------------使用默认解释器执行,不会执行shell脚本第一行,但是不能不写
注意
当使用 ./xxx.sh 和 bash xxx.sh 执行文件时,会创建一个子shell。
2.变量
变量分为环境变量(全局变量)和普通变量(局部变量)。
环境变量:可以在创建的shell以及它的子shell中使用。
普通变量:只能在当前shell中使用。
若想要将变量设置为全局变量,则需要用 export 将指定的变量导出为全局变量。
export 变量名 //定义全局变量
export 变量名=变量值 //定义全局变量并修改或赋值变量值
export -n 变量名 //取消定义的全局变量变成局部变量
定义变量和清除变量
定义变量: 变量名=value
引用变量: $变量名
清除变量: unset 变量名
[root@group7 new]# vim hello.sh
#!/bin/bash
number=5
echo $number
#清除变量
unset number
echo $number
[root@group7 new]# sh hello.sh
5
从键盘获取值(read)
#read [选项] [变量名]
#-d :表示定界符,一般情况下是以IFS为参数的间隔,但是通过-d,我们可以定义一直读到出现执行的字符位置。例如read –d madfds value,读到有m的字符的时候就不在继续向后读,例如输入为 hello m,有效值为“hello”,请注意m前面的空格等会被删除。这种方式可以输入多个字符串,例如定义“.”作为结符号等等。
#-e :只用于互相交互的脚本,它将readline用于收集输入行。读到这几句话不太明白什么意思,先跳过。
#-n :用于限定最多可以有多少字符可以作为有效读入。例如echo –n 4 value1 value2,如果我们试图输入12 34,则只有前面有效的12 3,作为输入,实际上在你输入第4个字符‘3’后,就自动结束输入。这里结果是value为12,value2为3。
#-p :用于给出提示符,在前面的例子中我们使用了echo –n “…“来给出提示符,可以使用read –p ‘… my promt?’value的方式只需一个语句来表示。
#-r :在参数输入中,我们可以使用’/’表示没有输入完,换行继续输入,如果我们需要行最后的’/’作为有效的字符,可以通过-r来进行。此外在输入字符中,我们希望/n这类特殊字符生效,也应采用-r选项。
#-s :不讲输入内容显示。最典型的就是输密码。
#-t :用于表示等待输入的时间,单位为秒,等待时间超过,将继续执行后面的脚本,注意不作为null输入,参数将保留原有的值
[root@group7 new]# vim hello.sh
#!/bin/bash
num=10
echo $num
read num2
echo "num2的值为$num2"
[root@group7 new]# sh hello.sh
10
2
num2的值为2
当我们在键盘上输入值时,为了使用户有更好的体验,往往会进行输入提示;那么shell脚本能不能也进行提示呢?答案是当然可以。
我们只需要在 read 后面加 -p ,再输入给定的提示,就可以在用户输入内容时进行提示。话不多说,上案例:
读取多个值
只读变量(readonly)
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
位置变量
变量 | 说明 |
$n | n为数字,$0为脚本名称,$1~$9为参数,10以上需要用{ }包起来,如${10}。 |
$@ | 将输入参数以空格分开为整体 |
$* | 将输入参数作为整体 |
$# | 显示参数个数 |
$$ | 显示当前运行的脚本PID号 |
示例: sh a.sh 你 我 他 它
变量运算
整数运算 -expr、let
expr可以运算,并且将结果输出。注意,该命令后需要用空格把运算符和数字分隔开。否则不会输出结果。
let运算,只能进行运算,不会输出结果。
小数运算bc
bc运算,可以进行小数运算,并且使用的是交互模式。输入内容后,可以直接得到运算结果。此外,还支持比较运算,真为1,假为0 。若不想进行交互式,则可以使用管道符进行操作。
还可以使用 scale=xxx,指定保留几位小数。
运算符号(()),[ ]
3.条件测试
文件测试
1.检查文件/home/cut.txt文件是否存在
①使用脚本操作
②使用命令操作
[root@group7 home]# ls
bajie cut.txt inotify.sh mike monkey.txt ooo shaseng tangseng wukong
[root@group7 new]# test -e /home/cut.txt && echo "The command $_ found." || echo "The command $_ not found."
the /home/cut.txt is found
# $_指上一个执行的命令的最后一个参数
字符串测试
数值测试
我们用一个脚本来进行举例
#!/bin/bash
read -p "please enter a value:" a #输入a,b的值
read -p "please enter b value:" b
if [ $a -eq 5 ] #当a=b时,输出a=b
then
echo "The value $a = 5"
fi
if [ $a -gt $b ] #当a>b时,输出a>b
then
echo "The value $a gt $b"
fi
if [ $a -lt $b ] #当a<b时,输出a<b
then
echo "The value $a lt $b"
fi
if [ $a -ne $b ] #当a不等于b时,输出a!=b
then
echo "The value $a != $b"
fi
逻辑操作符
#!/bin/bash
read -p "enter a:" a
if [ "$a" -eq 25 ] || [ "$a" -eq 10 ]
then
echo "test success"
else
echo "test false"
fi
#或者可以这样写
if [[ $a -eq 25 || $a -eq 10 ]]
then
echo "test success"
else
echo "test false"
fi
[root@group7 new]# sh luoji.sh
enter a:25
test success
test success
4. if条件语句
if条件语句语法
格式一:
if [条件1]; then
执行第一段程序
else
执行第二段程序
fi
格式二:
if [条件1]; then
执行第一段程序
elif [条件2];then
执行第二段程序
else
执行第三段程序
fi
单分支if语句
#!/bin/bash
#提示用户输入密码
read -p "请输入密码:" passwd
#用if判断,只有输出正确时才输出,错误则不输出
if test "$passwd" == "123456"
then
echo -e "\npassowrd currect"
fi
多分支语句
我们把上面的单分支语句进行优化,让他输入错误时,也进行输出提示。
#!/bin/bash
#提示用户输入密码
read -p "请输入密码:" passwd
#用if判断
if test "$passwd" == "123456"
then
echo -e "\npassowrd currect"
elif test "$passwd" == ""
then
echo -e "your not enter password"
else
echo -e "\npassword not current"
fi
5. case条件语句
case语句的语法
1 | case expression in
2 | PAT1)
3 | 执行语句
4 | ;;
5 | PAT2)
6 | 执行语句
7 | ;;
8 | *)
9 | 默认执行语句
10| ;;
11| esac
case语句实践
写一个shell脚本,输入数字,返回星期几
#!/bin/bash
read -p "请输入数字,结果返回星期:" week
case $week in
1)
echo "星期一";;
2)
echo "星期二";;
3)
echo "星期三";;
4)
echo "星期四";;
5)
echo "星期五";;
6)
echo "星期六";;
7)
echo "星期天";;
"")
echo "输入为空";;
esac
6.for循环语句
语法格式
for 变量名 in 取值列表
do
命令
done
for 循环的次数,取决于 取值列表中的变量的数目
或者可以使用另外一种写法
当使用(( ))时,可以使用C语言的一些命令
for循环显示当前目录下的文件
#!/bin/bash
for i in `ls`
do
echo $i
done
for循环打印99乘法表
#!/bin/bash
for ((i=1;i<=9;i++))
do
for ((j=1;j<=i;j++))
do
echo -n -e "$i*$j=$[i*j]\t"
done
echo
done
7.while循环和until循环
while循环语法
while 条件
do
代码段
done
while循环示例
#!/bin/bash
i=1
while [ $i -le 10 ]
do
echo $i
let i++;
done
until循环语法
until循环与while循环类似,但是until循环判断条件与while循环相反,只有当until的条件为假时,才会继续运行;条件为真时,会退出循环。
until 条件
do
程序体
done
until循环示例
#!/bin/bash
var=1
until [ $var -gt 3 ] #条件为 $var > 3
do
echo "$var"
var=$(( var + 1 ))
done
8.break,continue和exit
break语句用于从for、while、until等循环退出。
continue语句用于跳过循环体中剩余的命令,直接回到循环顶部,开始下一次循环。
exit语句,退出当前shell
break示例
写一个脚本,从键盘输入数字,为正数时相加,为负数时退出循环,并打印最后结果
#!/bin/bash
sum=0
while read n
do
if ((n > 0))
then
((sum += n))
else
echo "sum小于0"
break
fi
done
echo "sum=$sum"
continue示例
写一个脚本,遍历1-10,当为5时,不输出
#!/bin/bash
for i in {1..10}
do
if [ $i -eq 5 ]
then
continue
else
echo $i
fi
done
exit示例
创建 exit.sh 文件,并执行,查看返回值
#!/bin/bash
echo "hello world"
exit 8
echo "ni hao"
#执行脚本
[root@group7 new]# sh exit.sh
hello world
[root@group7 new]# echo $? #查看返回值
8
9.函数
当我们使用for循环,if条件判断来写脚本时,常常因为嵌套过多导致,分不清到底在哪一个循环中。这时候,我们能可以使用函数封装,从而使代码更为简洁易懂。
定义函数的格式
#方法一 如果有function关键字,则可以省略括号()
function function_name(){
函数体
}
#方法二
function_name(){
函数体
}
调用函数格式
#调用函数时,直接写函数名,后面可以跟参数
案例演示
定义一个函数,计算参数和
#!/bin/bash
function num_sum() {
local sum=0
for i in $@
do
((sum+=i))
done
echo $sum
}
num_sum 10 20 30
#执行文件
[root@group7 new]# sh function.sh
60
函数中的return
return 从函数中返回,用最后状态命令决定返回值
return 0 无错误返回
return 1 有错误返回
函数案例
统计路径下文件数目
#!/bin/bash
sum=0
read -p "请输入路径:" path
cd $path
for i in `ls -r *`
do
if [ -f $i ]
then
let sum++
echo "filename is: $i"
fi
done
echo "The file numbres is: $sum"
shell脚本之猜数字游戏
#!/bin/bash
echo "----- 欢迎登录本游戏 -----"
echo "数字范围为 1-50 之间"
random_num=$(($RANDOM%50+1))
while :
do
read -p "请输入 1-50 的随机数:" number
if [[ $number == "" ]]
then
echo "输入格式有误,请重新输入"
continue
elif [ $number -eq $random_num ]
then
echo "猜对了,随机数为 $random_num"
exit
elif [ $number -gt $random_num ]
then
echo "$number,猜大了,请继续"
elif [ $number -lt $random_num ]
then
echo "$number,猜小了,请继续"
fi
done
#测试脚本
[root@group7 hanshu]# sh guess_num.sh
----- 欢迎登录本游戏 -----
数字范围为 1-50 之间
请输入 1-50 的随机数:25
25,猜大了,请继续
请输入 1-50 的随机数:15
15,猜大了,请继续
请输入 1-50 的随机数:12
12,猜小了,请继续
请输入 1-50 的随机数:13
13,猜小了,请继续
请输入 1-50 的随机数:14
猜对了,随机数为 14