本篇博客
1.shell介绍
2.shell规范
3.shell语法
3.1变量
3.2参数传递
3.3重定向
3.4程序的结构
1.shell介绍
通常所说的shell就是shell脚本,它是一门脚本语言,弱类型
shell是一段应用程序,是用户和操作系统交互的一个桥梁,shell通常就是shell脚本
shell弱类型语言,在定义变量不需要指定变量的类型
2.shell规范
1.第一行内容为:#!/bin/bash
2.shell中的注释:#
3.shell脚本结尾:是以.sh结尾的文件
3.shell语法
3.1 变量
1)变量名=变量值
注意:等于号两边没有空格
正确的:
name=haha
错误的:
name=ha ha
2)变量命名规范:不能以数字开头,字母、数字、下划线组成
3)输出变量内容:echo $变量名
echo $name
4)变量的释放:unset 变量名
unset name
检查:再打印name,是没有值的
echo $name
5)特殊的变量,带有空格的变量定义:
双引号""
name="ha ha"
检查:echo $name,值:ha ha
1.如果变量值中存在$变量名的话,那么输出结果将会是变量名对应的变量值
name="ha ha" #这里的name定义是单引号还是双引号,无所谓。主要下面m的定义要是双引号。 m="zhangyuqi$name" echo $m
结果为:
2.如果想原样输出内容,可以在$变量名前面加转义字符
name="ha ha" h="zhangyuqi $name" echo $h
结果为:
单引号:''
name2='zhang san'
检查:echo $name,值:zhang san
如果变量值中存在$变量名,那么将原样输出
name="ha ha" n='fanbb $name' echo $n
结果为:
反单引号``
存放的是命令
unset m #释放m echo $m #打印没有,释放完成 m=`ls` #反单引号在数字1的左边 echo $m
结果为:
练习
1. 练习:使用shell脚本,输出当前所在的目录
步骤
1.新建.sh文件
vim script1.sh
2.在文件中编写shell脚本
#!/bin/bash m=`pwd` echo $m
注意:vim脚本编辑区命令
i-----插入 esc----退出插入模式 :wq------退出
3.执行
这样直接执行,提示权限不够。所以以方式1或者方式2执行。
./script1.sh
方式1:sh 文件名.sh
sh script1.sh
结果为:输出当前所在的目录
方式2:
- 1.添加x权限:chmod +x 文件名.sh
- 2. 执行 ./文件名.sh
chmod +x script1.sh
./script1.sh
结果为:也输出当前所在的目录
2.练习:计算/etc目录下有多少个文件,用shell脚本实现
步骤:
1.新建.sh文件
vim script2.sh
2.在文件中编写shell脚本
#!/bin/bash #进入etc目录下 cd /etc filenum=`ls -l|wc -l` echo "该目录下有$filenum个文件" #这里一定是双引号
命令:统计文件个数
ls -l|wc -l
注意: ls -l:显示文件信息 | :管道符 wc -l:可以统计文件行数(个数)
3.执行文件
sh script2.sh
结果为:
read:通过从键盘输入
改进:实现统计任何指定目录下的文件个数
read的格式:
read 变量名
1.变量名可以有一个或者多个,变量名用空格隔开,变量值用空格隔开
输出一个变量
read a
输入:fanbb
echo $a
结果为:
把之前的a释放掉
unset a
echo $a # 空的,释放完成
输出多个变量
注意:输入变量时,变量与变量之间也要空格。
read a b
输入:fanb zhangyuqi
注意:输入值时。值和值也需要空格。
echo $a
结果为:
echo $b
结果为:
2.如果变量值多于变量名,那么将会把多余的变量值赋值给最后一个变量
read a b
输入:fanbb zhangyuqi haha
echo $a
结果为:
echo $b
结果为:把多余的值,赋值给最后一个变量。
例:实现统计任何指定目录下的文件个数
1.直接复制一份2.sh文件,然后在上面改。
cp script2.sh script3.sh
2.修改文件,进入3.sh文件
#!/bin/bash
#输入目录
read dir
#进入指定目录下
cd $dir
filenum=`ls -l|wc -l`
echo "$dir目录下有$filenum个文件"
3.执行文件
sh script3.sh
输入:/etc
结果为:
sh script3.sh
输入:/tnp
结果为:
3.可以添加提示信息:read -p "提示的内容" 变量名
1.拷贝3.sh文件
cp script3.sh script4.sh
2.修改4.sh文件
#!/bin/bash #输入目录 read -p "请输入目录:" dir #进入指定目录下 cd $dir filenum=`ls -l|wc -l` echo "$dir目录下有$filenum个文件"
3.执行文件
sh script4.sh
请输入目录:/tnp
结果为:
3.2参数传递
向.sh文件中传递数据
1)格式
命令 文件名 参数。如:
sh script4.sh /etc
2)文件中接收参数的方式
$1--->表示第一个参数
例1:6.sh文件内容
#!/bin/bash echo "这个数据是$1"
执行文件
sh script6.sh 100
结果为:
$2---》表示第二个参数
例2:6.sh文件内容
#!/bin/bash echo "这个数据是$1" echo "这个数据是$2"
执行文件:
sh script6.sh 100
结果为:
执行文件:
sh script6.sh 100 cheng
结果为:
$3---》第三个参数
例3:6.sh文件内容
#!/bin/bash echo "这个数据是$1" echo "这个数据是$2" echo "这个数据是$4"
执行文件:
sh script6.sh 100 chen
结果为:
执行文件:
sh script6.sh 100 chen 200
结果为:注意,第三个数据是没有拿到的。因为$4是接受第4个数据。
执行文件:
sh script6.sh 100 chen 200 300
结果为:$4拿到了第四个数据。
$n--->表示第n个参数
$0--->代表文件名
例4:6.sh文件内容
#!/bin/bash echo "这个数据是$1" echo "这个数据是$2" echo "这是$0"
执行文件:
sh script6.sh 100 chen
结果为:
$@:显示全部参数
例5:6.sh文件内容
#!/bin/bash echo "这个数据是$1" echo "这个数据是$2" echo "这是$0" echo "这是$@"
执行文件:
sh script6.sh 100 chen
结果为:显示所有参数
$#:显示参数的个数
例5:6.sh文件内容
#!/bin/bash echo "这个数据是$1" echo "这个数据是$2" echo "这是$0" echo "这是$@" echo "这是$#"
执行文件:
sh script6.sh 100 chen
结果为:显示参数个数
例6:(改进)实现统计任何指定目录下的文件个数
1.复制文件2.sh
cp script2.sh script5.sh
2.vim进入5.sh文件
vim script5.sh
修改为:
#!/bin/bash #进入etc目录下 cd $1 filenum=`ls -l|wc -l` echo "该目录下有$filenum个文件"
3.执行文件
sh script5.sh /etc
结果为:
3.3重定向:
重定向:把命令的内容输出到文件中
理解:输入ls,会把结果显示在终端上,如下图。但是想把结果输出到文件中,就要重定向。
总结:
正确命令: 用数字1表示, >覆盖,>>追加
错误命令:用数字2表示,>覆盖,>>追加
正确的命令:1表示
覆盖:> 格式为:
命令 1>文件名
例1:ls 1>a.txt
ls 1>a.txt
查看a.txt内容:
cat a.txt
结果为:
例2: 把/etc目录写的文件名放在a.txt文件里
ls /etc 1>a.txt
结果为:
追加:>> 格式为:
命令 1>>文件名
例:
ls 1>>a.txt
结果为:下面是当前的文件,上面是之前的文件。没有被覆盖。
错误的命令:2表示
理解:没有的命令,乱输入的。也是可以重定向到文件中来。
覆盖:> 格式为:
命令 2>文件名
例1:
cd sajdsdj 2>b.txt
结果为:
例2:
asdhkd 2>b.txt
结果为:之前的就会覆盖掉。
追加:>> 格式为:
命令 2>>文件名
例3:
cd sajdsdj 2>>b.txt
结果为:之前的结果就没有被覆盖掉。
3.4程序的结构
1 分支结构
- if...else分支
- if...elif...else分支
- case分支
2 循环结构
for循环
1)if...else分支:
逻辑运算符:-a -o !
比较运算符:-ge -gt -lt -le -eq -ne
测试文件的状态:test 参数 文件名
字符串判断:== ,!=
文件判断:-d -e -f -w -r -x .....
格式
格式1
if [ 条件 ]
then
语句
else
语句
fi
注意:
1.条件两边要有空格
2.多个条件间要有空格
3.if后面要有空格
4.条件中如果存在变量,那么变量的两边要有双引号
如:name="chenliang"---->echo $name, N="chenliang"(意思就是:如果不加双引号,输出的就是chengliang,而不是“chengliang”)
格式2
if [ 条件 ];then
语句
else
语句
fi
1.字符串的比较
练习1:判断 /etc目录是否为空(格式1)
ls /etc
知识点:字符串的比较:==判断是否相等,!=判断是否不相等
1. 7.sh文件内容
#!/bin/bash dir=`ls /etc` if [ "$dir" == "" ] then echo "目录为空" else echo "目录不为空" fi
2.执行文件:
sh script7.sh
3.结果为:
2.判断是否为空
练习1-1:判断 /etc目录是否为空(格式2)
1. 7.sh文件内容
#!/bin/bash dir=`ls /etc` if [ "$dir" == "" ];then echo "目录为空" else echo "目录不为空" fi
2.执行文件
sh script7.sh
3.结果为:
练习2:通过用户输入任意目录判断是否为空
1. 8.sh文件内容
#!/bin/bash read -p "请输入目录:" dir b=`ls $dir` if [ "$b" == "" ];then echo "目录为空" else echo "目录不为空" fi
2.执行文件
sh script8.sh
请输入目录:/etc
3.结果为:
4.在当前目录创建一个空文件夹:mkdir aaa
5.执行文件,输入aaa,结果为空。
3.逻辑运算符
练习3:判断用户输入的用户名和密码是否为admin 123456,如果是则提示登录成功,否则提示失败
知识点:逻辑运算符
且:-a
或者: -o
非: !
1. 9.sh文件
#!/bin/bash read -p "请输入用户名和密码:" username passwd if [ "$username" == "admin" -a "$passwd" == "123456" ];then echo "登陆成功" else echo "登陆失败" fi
2.执行文件
sh script9.sh
请输入用户名和密码:admin 123
3.结果为:
请输入用户名和密码:admin 123456
4.结果为:
4.比较运算符
练习4:输入数字,判断是否大于0,如果大于0则将该数字-1并输出,否则+1输出
知识点:数字间比较--->比较运算符
-eq ---》判断是否相等
-ne--->判断是否不相等
-gt---->判断是否大于
-ge --->判断是否大于等于
-lt ----->判断是否小于
-le ---->判断是否小于等于
5.数字变量操作
下面都可以表示:i+1 (如果想表示i-1,就把下面的+换成-就可以了)
((i++)) ((i+=1)) i=$[$i+1] let i=i+1 i=$(($i+1))
例: 输入数字,判断是否大于0,如果大于0则将该数字-1并输出,否则+1输出
#!/bin/bash read -p "请输入数字:" num if [ "$num" -gt 0 ] then ((num--)) echo "$num" else ((num++)) echo "$num" fi
执行文件:
sh script10.sh
结果为:
结果2为:
关于内容中的tab空格:上面的空格一定要。下面的tab空格是为了好看。最好也要。
6.测试文件的状态:test
练习5:判断用户输入的目录是否存在,如果存在则统计目录下的文件个数,否则提示用户该目录不存在
涉及知识点:测试文件的状态
test 参数 变量名
参数
- -e表示文件是否存在
- -f 表示文件是否存在且为文件
- -d 表示文件名是否存在且为目录
- -r 可读
- -w 可写
- -x 可执行
例:判断用户输入的目录是否存在,如果存在则统计目录下的文件个数,否则提示用户该目录不存在
#!/bin/bash read -p "请输入一个目录:" dir if test -d $dir then filenum=`ls -l $dir|wc -l` echo "$dir目录下有$filenum个文件" else echo "该目录$dir不存在" fi
执行文件:
sh script11.sh
结果为:
结果2为:
结果3为:
2)if...elif...else分支
格式
if [ 条件 ] #如果条件成立,走then后面的代码
then
语句
elif [ 条件 ] #如果上面的条件不成立,判断这个条件是否成立,成立:走then后面的代码。不成立:判断后面的elif条件。
then
语句
elif [ 条件 ]
then
语句
....
else
语句
fi
7.文件判断
练习1:判断学生的成绩,范围在90-100提示优秀,80-90之间提示良好,70-80之间则提示一般,60-70之间提示及格。其他则提示不及格
练习2:判断用户输入的内容是否为空,为空则提示,不为空则判断是否为目录,不为目录则判断是否为文件,否则提示错误信息
涉及知识点:文件判断
- -r -r filename 文件是否存在且可读
- -w -w filename 文件是否存在且可写
- -x -x filename文件是否存在且可执行
- -f -f filename 文件是否存在且是普通文件
- -d -d filename 文件是否存在且是一个目录
- -e -e filename 文件是否存在
- -n -n str1 字符串长度是否不等于0
- -z -z str2 字符串长度是否等于0
例1:判断学生的成绩,范围在90-100提示优秀,80-90之间提示良好,70-80之间则提示一般,60-70之间提示及格。其他则提示不及格
#!/bin/bash #提示用户输入分数 read -p "请输入你的分数:" score #进行判断 if [ "$score" -ge 90 -a "$score" -le 100 ] then echo "优秀" elif [ "$score" -ge 80 -a "$score" -lt 90 ] then echo "良好" elif [ "$score" -ge 70 -a "$score" -lt 80 ] then echo "一斑" elif [ "$score" -ge 60 -a "$score" -lt 70 ] then echo "及格" else echo "西西睡把" fi
结果为:
例2:判断用户输入的内容是否为空,为空则提示,不为空则判断是否为目录,不为目录则判断是否为文件,否则提示错误信息
涉及知识点:文件判断
注意:类似前面的test的用法。这里就是省略了test。前面有test的是可以不用[ ],但是这里要用[ ]。
-r -r filename 文件是否存在且可读
-w -w filename 文件是否存在且可写
-x -x filename 文件是否存在且可执行
-f -f filename 文件是否存在且是普通文件
-d -d filename 文件是否存在且是一个目录
-e -e filename 文件是否存在
-n -n str1 字符串长度是否不等于0
-z -z str2 字符串长度是否等于0
例2:判断用户输入的内容是否为空,为空则提示,不为空则判断是否为目录,不为目录则判断是否为文件,否则提示错误信息
#!/bin/bash #提示用户输入内容 read -p "请输入内容:" con if [ -z "$con" ] then echo "为空" elif [ -d "$con" ] then echo "是目录" elif [ -f "$con" ] then echo "是文件" else echo "错误" fi
执行的结果:
3)case分支:
格式:
和 if------elif-----else 分支挺像的。如果满足第一个判断,就不往后判断了。如果不满足,就往后判断。如果都不满足,就走最后一个。
case $变量名 in "值") 语句;; "值") 语句;; "值") 语句;; ..... *) 语句;; esac
注意:
1.case这一行的最后为in
2. ;;表示语句的结束(;;是两个英文分号)
3. *:表示默认
4.esac:表示case语句结束
5.值:可以是字符串、数字、还可是区间范围【0-9】之间(注意:区间是不用加双引号的。)
练习
练习1:输入一个字母,判断该用户选择哪款产品,A:笔记本 B:电饭煲 C:小台灯
#!/bin/bash #提示用户输入信息 read -p "请输入内容:" con case $con in "A") echo "笔记本";; "B") echo "电饭煲";; "C") echo "小台灯";; esac
注意:上面的也可以不加默认的 。*)
执行结果为:
练习2:请输入对客服的满意度,【0-3】不满意,【4-6】满意,【7-9】非常满意
注意:区间是不用加双引号的。
#!/bin/bash #提示用户输入信息 read -p "请做出评价:" con case $con in [0-3]) echo "不满意";; [4-6]) echo "满意";; [7-9]) echo "非常满意:";; esac
执行结果为:
2 循环结构:
1)for循环
2)while循环
for循环
格式:
for 变量名 in 列表 do 语句 done
练习
输出1-10之间的数
#!/bin/bash #循环 for i in 1 2 3 4 5 6 7 8 9 10 do echo $i done
执行结果为:
注意:如果到10000呢,所以是不好的,这种方法。
改进版:
seq start size max
- start:开始点
- size:间隔
- max:结束点
注意:如果size的值为1,则可以省略
例1:1-10之间的数
#!/bin/bash #循环 for i in `seq 1 1 10` do echo $i done
注意:seq 1 1 10是一个命令,所以要加反单引号``。
执行结果:
例2:1-10之间的奇数。
#!/bin/bash #循环 for i in `seq 1 2 10` do echo $i done
执行结果为:
例3:步长为1可以省略。
#!/bin/bash #循环 for i in `seq 1 10` do echo $i done
执行结果为:
while循环
格式:
while [ 条件 ]
do
命令
done
变量间加运算(三种形式都可以。如果想要减法运算,加号换成减号就可以了。)
s=$(($s+$i)) s=$[$s+$i] ((s=$s+$i))
变量的变化:i=i+1---->表示的形式
多个变量间操作------>表示的形式
例:求1-100之间的和
#!/bin/bash i=1 sum=0 while [ "$i" -le 100 ] do sum=$(($sum+$i)) ((i++)) done echo $sum
执行的结果为: