本节所讲内容:
. shell 基本语法
. 变量
. 表达式
. 判断语句
. if表达式
什么叫shell
【例】先看一个简单的shell程序
[root@xuegod163 ~]# vim example01.sh #写入一下内容 #!/bin/bash #This is to show what a example looks like. echo "Our first example" echo "We ar currently in the following directory" pwd echo "This directory contains the following files" ls [root@xuegod163 ~]# chmod +x example01.sh #赋予一个可执行权限 [root@xuegod163 ~]# ./example01.sh #执行该shell程序 Our first example We ar currently in the following directory /root This directory contains the following files anaconda-ks.cfg Music Desktop Pictures Documents Public Downloads qla2xxx-8.07.00.16.06.0-k-dd-rhel6u5-2.6.32-431.el6-x86_64.iso example01.sh Templates install.log Videos install.log.syslog
注释:
#!/bin/bash #!跟shell命令的完全路径。 作用:显示后期命令以哪种shell来执行这些命令。如不指shell,以当前shell作为执行的shell。
#This is to show what a example looks like. 在shell中以#开始头表示,整个行就被当作一个注释。执行时被忽略。
shell程序一般以.sh结尾,表名这是一个shell程序
1.1 shell编程
先了解一些基本概念
编程语言:机器语言、汇编语言、高级语言
静态语言:编译型语言,如C、C++、java等
动态语言:php、shell、python、perl等
编译器:又称为解释器,可以将人类的语言翻译成机器理解的语言
弱类型:变量随时声明,shell就是一种弱类型的编程语言
强类型:变量在适用前必须事先声明
1.2 创建shell程序的步骤
第一步:创建一个命令和控制结构的shell文件。
第二步:赋予这个文件一个可执行的权限,使用chmod +x
第三步:执行。
方法1:./ example01.sh
方法2:使用绝对路径。如[root@xuegod63 ~]# /root/ example01.sh。
方法3:使用bash或sh来执行。[root@xuegod63 ~]# bash example01.sh。这种执行方法可以没有执行权限。
shell变量的运用
变量
变量是shell传递数据的一种方法。变量是用来代表每个值的符号名。Shell变量分为两类,分别为临时变量和永久变量。
临时变量:是shell程序内部定义的变量,其使用范围仅限于定义它的程序,对其它程序不可见。
永久变量:也就是linux系统的环境变量,其值不随shell程序的执行而消失或改变。
【例】
[root@xuegod163~]# echo $PATH /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin [root@xuegod163 ~]# echo $HOME /root
用户自定义变量:由字母或下划线开头(不允许数字开头),右面有字母、数字或下划线组成,并且大小写字母的意义不同。变量名的长度没有限制。
注:使用变量时,要在变量名前加上前缀“$”
2.2 主要的赋值类型
2.2.1 变量赋值
赋值号“=”两边应没有空格
【例】
[root@xuegod63 ~]# A=aaa [root@xuegod63~]# A = aaa bash: A: command not found
2.2.2将命令的执行结果赋给变量
【例】
[root@xuegod163 ~]# A=`date` [root@xuegod163 ~]# echo $A Sat Jul 25 20:59:47 CST 2015
2.2.3 变量的传递
【例】
[root@xuegod163 ~]# B=$A [root@xuegod163 ~]# echo $B Sat Jul 25 20:59:47 CST 2015
2.2.4利用变量和其他字符串组成一个新的字符串
【例】
[root@xuegod163 ~]# MYDIR=/home/xuegod [root@xuegod163 ~]# echo $MYDIR/zhangsan /home/xuegod/zhangsan [root@xuegod163 ~]# DAY=Mon [root@xuegod163 ~]# echo Today is ${DAY}day Today is Monday
2.2.5 给变量赋值多个单词
【例】
[root@xuegod63 test]# NAME="mike Ron" [root@xuegod63 test]# echo $NAME mike Ron [root@xuegod63 test]# NAME='shenmk' [root@xuegod63 test]# echo $NAME shenmk
2.2.6 单引号的双引号的区别
单引号:之间的内容原封不动的指定给了变量
双引号:之间的特殊符号的含义保留
【例】
[root@xuegod63 ~]# NAME="mike Ron $NAME" [root@xuegod63 ~]# echo $NAME mike Ron shenmk [root@xuegod63 ~]# NAME='mike Ron $NAME' [root@xuegod63 ~]# echo $NAME mike Ron $NAME
2.2.7 把命令当做变量进行定义
【例】
[root@xuegod63 ~]# wen=`date +%F` #利用反引号进行定义 [root@xuegod63 ~]# echo $wen 2015-07-25 [root@xuegod63 ~]# wen=$(date) #利用小括号加$进行定义 [root@xuegod63 ~]# echo $wen Sat Jul 25 20:59:47 CST 2015
2.3 变量的管理
2.3.1 列出所有的变量
set 命令
【例】
[root@xuegod63 ~]# set | grep DAY DAY=Mon
2.3.2 变量的删除
unset 命令
【例】
[root@xuegod63 ~]# echo $NAME mike Ron $NAME [root@xuegod63 ~]# unset NAME [root@xuegod63 ~]# echo $NAME
2.4.1 位置变量
Shell 解释执行用户的命令时,将命令行的第一个字作为命令名,而其它字作为参数。由出现在命令行上的位置确定为参数称为位置参数。使用$N 来表示
$0 获取当前执行shell脚本的文件名,包括脚本的路径
$n 获取当前执行shell脚本的第n个参数,当n大于9时用{n}表示
【例】
[root@xuegod163~]# vim ./example.sh #!/bin/bash Echo “$0” echo "$1" echo "$2" [root@xuegod163 ~]# ./example.sh /etc/passwd /etc/hosts ./example.sh /etc/passwd /etc/hosts
【例】位置变量在服务启动与停止中的应用
[root@xuegod63 ~]# vim /etc/init.d/vsftpd case "$1" in #相当于执行/etc/init.d/vsftpd $1 start) start #当选择 start 时调用 start 函数来启动服务 ;; stop) stop #当选择 stop 时调用 stop 函数来停止服务 ;; restart|reload) # 当选择 restart 或者 reload 时先停止服务再启动服务 stop start RETVAL=$? ;; echo $"Usage: $0 {start|stop|restart|try-restart|force-reload|status}" #当输入的$1不存在时,利用$0来打印当前执行的脚本
2.4.2 特殊变量
有些变量是一开始执行shell脚本时就会设定,且不能被修改,我们称之为特殊变量
$* 这个程序的所有参数
$# 这个程序的参数个数
$$ 这个程序的 PID
$! 执行上一个后台程序的 PID
$? 执行上一个命令的返回值
【例】
[root@xuegod63 ~]# vim z2.sh #!/bin/bash echo "$* 表示这个程序的所有参数 " echo "$# 表示这个程序的参数个数" touch /tmp/a.txt echo "$$ 表程序的进程 ID " touch /tmp/b.txt & echo "$! 执行上一个后台命令的 PID" echo "$$ 表程序的进程 ID " 执行结果: [root@xuegod63 ~]# ./z2.sh aaabbb ccc aaabbb ccc 表示这个程序的所有参数 3 表示这个程序的参数个数 3899 表程序的进程 ID 3901 执行上一个后台命令的 PID 3899 表程序的进程 ID
关于$?返回值的主要含义
0 |
运行成功 |
2 |
权限被拒绝 |
1-125 |
运行失败,命令错误或者参数错误 |
126 |
找到命令,但不能执行 |
127 |
未找到命令 |
128 |
命令被系统强制结束 |
2.5 变量的数值计算
用于执行简单的整数运算
格式:$((算术运算符))
常用的算术运算符
运算符 |
含义 |
++ -- |
递增和递减,可前置也可后置 |
+ - ! ~ |
一元运算的正负号逻辑与取反 |
+ - * / % |
加减乘除余数 |
= != |
相等不相等 |
<<= >>= |
比较大小 |
>><< |
向左位移向右位移 |
& ^ | |
位的与异或或 |
&& || |
逻辑与逻辑或 |
?: |
条件判断 |
【例】三种简单的赋值运算
[root@xuegod63 ~]# ((a=1+2**3-4%3)) #2**3 为 2的 3次方 [root@xuegod63 ~]# echo $a 8 [root@xuegod63 ~]# b=$((1+2**3-4%3)) [root@xuegod63 ~]# echo $b 8 [root@xuegod63 ~]# echo $((1+2**3-4%3)) #省去了定义一个变量 8
【例】递增递减的应用
[root@xuegod63 ~]# echo $((a+=1)) 9 [root@xuegod63 ~]# echo $((a++)) #等同与 a+=1 10 [root@xuegod63 ~]# echo $((a--)) 11 [root@xuegod63~]# echo $a #a++或 a--为先赋值再 a 加 1 或a 减 1 10 [root@xuegod63 ~]# echo $((--a)) 9 [root@xuegod63 ~]# echo $a #--a或++a 为先 a 加 1 或 a 减 1 再进行 a 的赋值 9
【例】比较大小
[root@xuegod63 ~]# echo $((1>2)) 0 [root@xuegod63 ~]# echo $((1<=2)) #真为 1 假为 0 1
【例】1到100所有整数的和
[root@xuegod63 ~]# echo $((100*(1+100)/2)) 5050
【例】一个简单的四则运算脚本
[root@xuegod63 ~]# vim operation.sh #!/bin/bash a=6 b=2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" 执行结果 : [root@xuegod63 ~]# sh operation.sh a-b=4 a+b=8 a*b=12 a/b=3 a**b=36 a%b=0
【例】写一个简单的计算器,并且有判断功能
[root@xuegod63 ~]# vim operation.sh #!/bin/bash functionEnternum(){ read -p "Please enter the first number:" a read -p "Please enter the second number:" b Judgenum } functionEnterchar(){ read -p "Please enter the transport operator:" c echo "****************" Judgechar } functionJudgenum(){ if [[ $a =~ ^[0-9]+$ && $b =~ ^[0-9]+$ ]]; then #注意=~两边的空格 Enterchar else echo "Digital input errors, please reenter num" Enternum fi } functionJudgechar(){ if [[ $c =~ "-"|"+"|"*"|"/"|"%" ]];then echo $(($a$c$b)) else echo "Digital input errors, please reenter char" Enterchar fi } while true doEnternum done
read命令
的基本用法
read的所用是从键盘读入数据赋值给变量
【例】对 read 的实验 #以空格为赋值分隔符
[root@xuegod63 ~]# read a b c 1 32 3 [root@xuegod63 ~]# echo $a $b $c 1 32 3 [root@xuegod63 ~]# echo $a 1
【例】read在shell脚本中的使用
[root@xuegod63 ~]# vim read.sh #!/bin/bash echo "input first second third :" read first second third echo "the first parameter is $first" echo "the second parameter is $second" echo "the third parameter is $third" 执行脚本: [root@xuegod63 ~]# ./read.sh input first second third : aa 11 33 the first parameter is aa the second parameter is 11 the third parameter is 33
3.2 常用的参数及用法
read answer 从标准输入读取一行并赋值给变量answer
read first last 从标准输入读取一行,直至遇到低于个空白符或换行符。把用户键入的第一个词存到变量first中,把改行的剩余部分保存到变量last中
read �Ca arrayname读入一组词,依次赋值给数组srrayname
read �Ce 在交互式shell命令行中启用编辑器
read �Cp prompt 打印提示符,等待输入,并将输入赋值给PEPLY变量
read �Cr line 允许输入包含反斜杠
expr命令
的基本用法
expr的作用是shell变量的算术运算
语法:expt表达式#运算符之间要有空格
【例】
[root@xuegod63 ~]# expr 3 + 5 8 [root@xuegod63 ~]# var1=8 [root@xuegod63 ~]# var2=2 [root@xuegod63 ~]# exp expandexportfsexpresskeys exportexpr [root@xuegod63 ~]# expr $var1 - 5 3 [root@xuegod63 ~]# expr $var1 / $var2 4 [root@xuegod63 ~]# expr $var1 * $var2 expr: syntax error [root@xuegod63 ~]# expr $var1 \* $var2 16
4.2 expr在脚本中的应用
[root@xuegod63 ~]# vim expr.sh #! /bin/sh a=10 b=20 c=30 value1=`expr $a + $b + $c echo "The value of value1 is $value1" value2=`expr $c / $b` echo "The value of value2 is $value2" value3=`expr $c \* $b` #整除 echo "The value of value3 is $value3" value4=`expr $a + $c / $b` echo "The value of value4 is $value4"
测试: [root@xuegod63~]# ./expr.sh The value of value1 is 60 The value of value2 is 1 The value of value3 is 600 The value of value4 is 11
4.3 复杂的运算
[root@xuegod63 ~]# var4=8 [root@xuegod63 ~]# expr `expr 5 + 11` / $var4 2
【例】
[root@xuegod63~]# var1=8 [root@xuegod63 ~]# var2=2 [root@xuegod63 ~]# var4=`expr $var1 / $var2` [root@xuegod63 ~]# echo $var4 4
【例】expr查找格式的应用
[root@xuegod63 ~]# expr "test.pub" : ".*.pub" && echo 1 || echo 0 8 # 8 为 test.pub 1 #左边为真则打印 1 [root@xuegod63 ~]# expr "test.pu1b" : ".*.pub" && echo 1 || echo 0 0 0 #左边为假则打印 0
【例】用expr判断是否为整数
[root@xuegod63 shell]# cat judge_int.sh read -p "input int: " a expr $a + 0 &>/dev/null #将所有执行信息重定向到null 中 [ $? -eq 0 ] && echo "int" || echo "input erro" #根据expr执行的返回值来判断是否为整数
的应用
格式:test 测试条件
注意:在使用“[]”简写test时,左中括号后面和右中括号前面必须有空格,如果没有空格则shell不能辨别表达式何时开始何时结束
5.2 测试的范围
测试的范围包括整数、字符串、文件
5.2.1 文件状态的测试
test -e:目标是否存在(exist)
test -d:是否为目录(directory)
test -f:是否为文件(file)
test -x:文件存在并且可执行
test -r file:文件存在并且可读
test -w file:文件存在并且可写
test -s file 测试大小是为空。是否为空文件
test File1 �Cef File2 两个文件具有同样的设备号和 i结点号
test File1 �Cnt File2 文件 1 比文件 2 新
test File1 �Cot File2 文件 1 比文件 2 旧
test �Cb File 文件存在并且是块设备文件
test �Cc File 文件存在并且是字符设备文件
test �Cf File 文件存在并且是正规文件
test �Cg File 文件存在并且是设置了组 ID
test �CG File 文件存在并且属于有效组 ID
test �Ch File 文件存在并且是一个符号连接(同-L)
test �Ck File 文件存在并且设置了 sticky 位
test �CL File 文件存在并且是一个符号连接(同-h)
test �Co File 文件存在并且属于有效用户 ID
test �Cp File 文件存在并且是一个命名管道
test �Ct FD 文件描述符是在一个终端打开的
test �Cu File 文件存在并且设置了它的 set-user-id 位
5.2.2 数值的比较
test -eq:等于(equal)
test -ne:不等于(Not equal)
test -gt:大于(greater than)
test -lt:小于(lesser than)
test -ge:大于或等于(greater or equal)
test -le:小于或等于(lesser or equal)
说明:也可以省略 test 写成:[ int1 -lt int2 ]
-eq |
== |
等于(equal) |
-ne |
!= |
不等于(not equa) |
-gt |
> |
大于(greater than) |
-ge |
>= |
大于或等于(greater or equal) |
-lt |
< |
小于(lesser than) |
-le |
<= |
小于或等于(lesser or equal) |
提示:“<”和“>””=”分别为大于、小于、等于,并且在[]中“<”“>”都要使用转义字符,在[[]]中不需要。
5.2.3 测试字符串和变量
test $str1 == $str2 是否相等
test $str1!= $str2 是否不相等
test $str1 如果$str1 不为空,则返回结果为真
test -n $str1 如果字符串长度为非零,则返回结果为真
test -z $str1 如果字符串长度为零,则返回结果为真
【例】判断两个字符是否相等
[root@xuegod63 ~]# vim if.sh #!/bin/bash echo "if test" var1="xuegod" var2="xxuexgod1" if [ "$var1" == "$var2" ] ; then #if [ -n $var1 ] ; then /bin/ls fi
【例】判断字符长度是否为 0
[root@xuegod63 test22]# cat if.sh #!/bin/bash echo "if test" var1="xuegod" #var1="" if [ -n "$var1" ] ; then /bin/ls fi
流程控制语句――if语句
作用:执行过程的自动化智能化的选择及处理,让重复操作更聪明一些
6.1 单分支if语句
语法:
if 条件
then
语句
fi
【例】“;”和“&&”在多命令时候的区别
[root@xuegod63 ~`]# ls /optt ; ls ls: cannot access /optt: No such file or directory example01.sh expr.sh read.sh z1.sh z.sh #分号为前后命令没有关系 [root@xuegod63~]# ls /optt&&ls ls: cannot access /optt: No such file or directory # &&为前一个命令不执行,后一个命令也不执行
6.2 双分支if语句
语法:
if 条件1 ; then
命令1
else
命令2
fi
【例】
[root@xuegod63 ~]# vim else.sh #!/bin/bash if [ -x /etc/passwd ] ; then #判断是否为可执行文件 /bin/ls else pwd fi 执行结果: [root@xuegod63~]# chmod +x else.sh [root@xuegod63 ~]# ./else.sh /root/test
6.3多分支if语句
语法:
if 条件 1 ;then
命令 1
elif条件 2 ;then
命令 2:
elif条件 3 ;then
命令 3
else
命令 4
fi
6.4 综合实例:测试文件类型
[root@xuegod63 ~]# vim elif.sh #!/bin/bash echo "input a file name:" readfile_name if [ -d $file_name ] ; then echo " $file_name is a dir" elif [ -f $file_name ] ; then echo " $file_name is file" elif [ -c $file_name -o -b $file_name ] ; then echo " $file_name is a device file" else echo " $file_name is an unknow file " fi
学神-IT-教育51cto技术交流群:468845589 快来上我们公开课吧!
学神MK老师:1273815479
学神ZY老师:3054384936
学神教育-学神-IT-1508-哀殇提供