1. shell类型、格式、执行方式、语句注释
shell种类:
linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。不同的Shell语言的语法有所不同,所以不能交换使用。每种Shell都有其特色之处,基本上,掌握其中任何一种 就足够了。在本文中,我们关注的重点是Bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统默认的Shell。在一般情况下,人们并不区分 Bourne Shell和Bourne Again Shell,所以,在下面的文字中,我们可以看到#!/bin/sh,它同样也可以改为#!/bin/bash。
shell格式:
一般格式如下:
#!/bin/bash
#comments
Your commands go here
首行中的符号#!告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程 序。如果首行没有这句话,在执行脚本文件的时候,将会出现错误。后续的部分就是主程序,Shell脚本像高级语言一样,也有变量赋值,也有控制语句。除第 一行外,以#开头的行就是注释行,直到此行的结束。如果一行未完成,可以在行尾加上”,这个符号表明下一行与此行会合并为同一行。
脚本的执行:
编辑完毕,将脚本存盘为filename.sh,文件名后缀sh表明这是一个Bash脚本文件。执行脚本有两种方法:
①要先将脚本文件的可执行权限,然后./filename.sh
chmod +x filename.sh
./filename.sh
②直接bash filename.sh,注意filename的文件开头需为#!/bin/bash,如果开头是#!/bin/sh,则用sh filename.sh; bash 和sh大多数时候可以通用,但是有时候会有些差别,建议统一使用bash
下面我们从经典的“hello world”入手,看一看最简单的Shell脚本的模样。
#!/bin/bash
#print hello world in the console window
a = "hello world"
echo $a
语句的注释:
单行注释:开头加上井号“#”
如果注释多行,则在每行开头都加上 #。其实很多人都不知道,shell是支持多行注释的
多行注释:
:<<BLOCK
......注释内容
BLOCK
举例:
#!/bin/bash
:<<BLOCK
author:michaelzeng
date:20160419
BLOCK
echo "hello world"
2. 判断语句if
if 基本语法:
if condition; then
command
else
command
fi
判断条件可以是字符串比较、数字大小比较或文件的判断等
字符串比较:
=:判断两字符串是否相等,注意=两边需要有空格,也可以使用双等号==,两边也要有空格,新手容易用 = 号进行数字比较,或忘记加空格,不加空格的时候=号是赋值
!=:判断两字符串是否不等
-n:比较字符串长度是否大于0,如果大于0则为“是”
-z:比较字符串长度是否等于0,如果等于则为“是”
整数比较符:
-eq:相等
-ge:大于等于
-le:小于等于
-ne:不等于
-gt:大于
注意只能比较整数,如果是比较浮点数,可利用bc命令处理,方法如下:bc命令可比较大小,正确返回1,错误返回0
a=1.85;b=2.2
if [ $(echo "$a < $b"|bc) -eq 1 ];then
echo "a < b"
else
echo "a > b"
fi
逻辑操作:
!:取反,与一个逻辑值相反的逻辑值。
-a:与(and),两个逻辑值为“是”,返回值为“是”,反之为“否”,也可用&&
-o:或(or),两个逻辑值有一个为“是”,返回值就为“是”;也可用||
其中:
-a 和-o主要用在单中括号里,[ ]; & &和||用在双中括号里,[[ ]]
以下两条语句是等价的
a=1;b=2
[[ $a -eq 1 && $b -eq 2 ]] && echo ok
[ $a -eq 2 -a $b -eq 2 ] && echo ok
有关单中括号和双中括号区别后续再讲
文件操作:
文件测试表达式通常是为了测试文件信息,一般由脚本来决定文件爱你是否应用备份、复制和删除。常用的文件操作符有:
-d:对象存在而且是目录返回“是”
-f:对象存在而且是文件返回“是”
-L:对象存在而且为符号连接返回“是”
-r:对象存在而且可读则返回“是”
-s:对象存在而且长度非零则返回“是”
-w:对象存在而且可写则返回值为“是”
-x:对象存在而且可执行则返回“是”
3. 循环结构
shell中常见的循环语句有for循环、while循环、until循环
for 循环
格式1:遍历循环
for $var in list;do
commands
done
举例:遍历某目录
for file in `ls /home`;do echo $file;done
格式2:条件循环
for (( cond1; cond2; cond3 ));do
commands
done
举例:for循环实现九九乘法表
#!/bin/bash
#三种实现数字序列方法
#for a seq 9;do
#for a {1..9};do
for((a=1;a<10;a++));do
for((b=1;b<=a;b++));do
echo -ne "$a*$b=$((a*b))\t"
if [[ $b -eq $a ]];then
echo
fi
done
done
输出结果:
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
while循环:
表达式成立,重复do和done之间的操作直至表达式不成立,语法如下:
while condition; do
commands
done
while常用于读取文件的每一行,然后进行相应的操作:
cat file.txt|while read line;do
echo $line
done
while read line;do
echo $line
done < file.txt
until循环:
表达式不成立,重复do到done之间的操作直到表达式成立,until和while语句可以进行转换,
until condition; do
commands
done
举例:以下脚本会输出1 2 1 2 3,until语句会多输出一个3,因为条件[ 3 -gt 3 ] 为false,仍会执行do 和done之间语句
#!/bin/bash
i=1
while [ $i -lt 3 ];do
echo $i
i=$(( i + 1 ))
done
i=1
until [ $i -gt 3 ];do
echo $i
i=$(( i + 1 ))
done
循环的控制: break 和 continue
在for、while和until循环中break可强行退出循环,break语句仅能退出当前的循环,如果是两层循环嵌套,则需要在外层循环中使用break。也可使用break 2,退出两层循环
举例:九九乘法表中跳过a=5的情况,自行对比break和break 2的输出区别
#!/bin/bash
#for a seq 9;do
#for a {1..9};do
for((a=1;a<10;a++));do
for((b=1;b<=a;b++));do
if [[ $a -eq 5 ]];then
break
#跳过2层循环
#break 2
fi
echo -ne "$a*$b=$((a*b))\t"
if [[ $b -eq $a ]];then
echo
fi
done
done
continue可以让脚本跳过过其后面的语句,执行下一次循环,如九九乘法表跳过b=2的情况
#!/bin/bash
#for a seq 9;do
#for a {1..9};do
for((a=1;a<10;a++));do
for((b=1;b<=a;b++));do
if [[ $b -eq 2 ]];then
continue
fi
echo -ne "$a*$b=$((a*b))\t"
if [[ $b -eq $a ]];then
echo
fi
done
done
4. 多分支结构
多分支可以用if语句,也可以用case。case的作用就是当字符串与某个值相同就执行那个值后面的操作。如果同一个操作对应多个值,则使用“|”将各个值分开。
if condition; then
command
elif condition; then
command
else
command
fi
case基本语法:
case $var in
pattern1)
commands ;;
pattern2 | pattern3)
commands ;;
*)
commands ;;
esac
5.交互模式:
①read命令,read -p ” ” var:提示用户输入,并将输入值赋给变量。
②select命令,用户可以从一组不同的值中进行选择。其语法如下:
select var in list; do
break;
done
如果没有break,会一直运行直到手动终止
举例:
#!/bin/bash
read -p "what is your name:" name
echo "hello $name"
#select 多选
select day in "201611121" "201611122" "201611123"; do
echo "day choice:$day"
select time in "23:24:11" "23:25:12" "23:26:13";do
echo "time choice:$time"
break
done
break
done
echo $day/$time