一、逻辑运算
变量:
本地变量、环境变量、局部变量、位置参数变量、特殊变量
变量赋值:name=value,export name=value,declare -x name=value
变量引用:$name,${name}
注意:有些时候{}不能省略,例如
echo “$valuemagedu.com”
echo “${value}magedu.com”
撤销:unset name
bash脚本编程,运行脚本
#!/bin/bash #称为shebang是bash脚本的默认开头行固定格式
# # #号后面是注释信息,不显示也不影响脚本执行结果
空白行 忽略不显示行
bash的配置文件
porfile类:登录式shell
bashrc类:非登录式shell
登录式shell:/etc/profile–>/etc/profile.d/*.sh–>~/.bash_profile–>~/.bashrc–>/etc/bashrc
非登录式shell:~/.bashrc–>/etc/bashrc–>/etc/profile.d/*.sh
算数运算
+,-,*,/,**(乘次方),%(求模取余)
在bash中默认数据类型都是字符串形式,做算数运行需要经特殊方法才可以
示例:
[root@localhost ~]# num1=2 [root@localhost ~]# num2=9 [root@localhost ~]# echo "${num1}+${num2}" 2+9 [root@localhost ~]# declare -i num3=5 [root@localhost ~]# declare -i num4=9 [root@localhost ~]# echo "${num3}+${num4}" 5+9
算术运算格式:
(1)let VAR=算数运算表达式
[root@localhost ~]# let ${num1}+${num2}
#默认不输出结果到屏幕,所以需要赋值给变量,再引用
[root@localhost ~]# let sum5=${num1}+${num2} [root@localhost ~]# echo ${sum5} 11
let 参数 [参数 …]
算术运算格式含义
num++,num– (两个减号不是大横线)变量后递增,后递减
++num,–num(两个减号不是大横线)变量前递增,前递减
+,-加法、 减法
!,~ 逻辑和按位求反
** 求幂运算(乘次方)
*,/,% 乘法,除法,求模(求余)
<<,>> 左和右移位
<=,>=,<,> 比较
==、 != 平等,不平等
& 按位与
^ 按位异或
| 按位或
&& 逻辑与
|| 逻辑或
expr ?expr: expr
条件运算符
=, *=, /=, %=,+=, -=, <<=, >>=,&=,^=,|= 赋值
变量也可以作为let 命令的参数
(2)VAR=$[算数运算表达式]
但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo
[root@localhost ~]# $[${num2}+${num3}] bash: 14: 未找到命令... [root@localhost ~]# echo "$[${num2}+${num3}]" 14
(3)VAR=$((算数运算表达式))
但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo
[root@localhost ~]# $((${num2}+${num3})) bash: 14: 未找到命令... [root@localhost ~]# echo $((${num2}+${num3})) 14
(4)expr EXPRESSION 或 VAR=$(expr EXPRESSION)
expr OPTION
示例:
[root@localhost ~]# num1=2 [root@localhost ~]# num2=4 [root@localhost ~]# expr ${num1} + ${num2} 6 [root@localhost ~]# sum=$(expr ${num1} \* ${num2}) #注意乘法*符号需要转意(原因是*号在有些场景中为glob通配符) [root@localhost ~]# echo "${sum}" 8
expr 参数的算术运算格式
ARG1 | ARG2
ARG1 是否为 null,也不是 0,否则为 ARG2
ARG1 & ARG2
ARG1 如果参数都不是 null 或 0,否则为 0
ARG1 < ARG2
ARG1 小于 ARG2
ARG1 <= ARG2
ARG1 小于或等于 ARG2
ARG1 = ARG2
ARG1 等于 ARG2
ARG1 != ARG2
ARG1 ARG2 不等于
ARG1 >= ARG2
ARG1 是大于或等于 ARG2
ARG1 > ARG2
ARG1 大于 ARG2
ARG1 + ARG2
ARG1 和 ARG2 的算术总和
ARG1 -ARG2
ARG1 减 ARG2 的算术差
ARG1 * ARG2
ARG1 和 ARG2 的算术积
ARG1 / ARG2
ARG1 除以 ARG2 的算术商
ARG1 % ARG2
ARG1 除以 ARG2 的算术余数
注意:算数运算格式内各参数彼此之间必须有空格,并且shell脚本不支持浮点型
增强型赋值:
变量做某种算数运算后回存至此变量中;
eg:
let i=$i+#
let i+=#
还有:+=,-=,*=,/=,%=
自增:
VAR=$[$VAR+1]
let VAR+=1
let VAR++
自减:
VAR=$[$VAR-1]
let VAR-=1
let VAR–
二、条件测试:
判断某需求是否满足,需要由测试机制来实现;
如何编写测试表达式以实现所需的测试;
(1)执行命令,并利用命令状态返回值来判断
0:成功
1-255:失败
(2)测试表达式
test EXPRESSION eg:test 3 -gt 2
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION两端必须有空白字符,否则有语法错误
bash的测试类型:
数值测试:数值比较
-eq:是否等于; eg:[ $num1 -eq $sum2 ]
-ne:是否不等于
-gt:是否大于
-ge:是否大于等于
-lt:是否小于
-le:是否小于等于
字符串测试:
==:是否等于;(字符串)
一个=号也可以由于赋值变量用=号,但是赋值并不应用到[]中,所以能够使用,但是还是推荐使用双=号
>:是否大于
<:是否小于
!=:是否不等于
=~:左侧字符串时候能够被右侧的PATTERN所匹配;(模糊匹配而非精确匹配)
示例:
[root@localhost ~]# [[ tom =~ tom ]] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ tom =~ om ]] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ tom =~ o ]] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ tom =~ x ]] [root@localhost ~]# echo $? 1
-z “STRING”:判断指定的字符串是否为空,空为真,不空为假
-n “STRING”:判断指定的字符串是否为不空,不空为真,空为假
注意:(1)字符串测试时:字符串要加引号,表示引用有变量命令””,没有变量命令使用”
(2)作比较时,尽量使用[[]];
(3) 但是在组合测试时,[[]]有时会有语法错误,所以可以使用[]
示例:
[root@localhost ~]# [ var1 == var1 ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [ var1 == Var1 ] [root@localhost ~]# echo $? 1 [root@localhost ~]# [ var1 == ${Var2} ] -bash: [: var1: 期待一元表达式 [root@localhost ~]# [ var1 == "${Var2}" ] [root@localhost ~]# echo $? 1 [root@localhost ~]# [ a > b] -bash: [: 缺少 `]' [root@localhost ~]# [ a > b ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [ a < b ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [ "a" < "b" ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [ "a" > "b" ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [[ "a" > "b" ]] [root@localhost ~]# echo $? 1
文件测试:
存在性测试:
-a FILE 少使用
-e FILE 推荐使用
文件存在则为真,否则为假
存在性及类型测试:
-b FILE:是否存在并且为块设备文件;
-c FILE:是否存在并且为字符设备文件;
-d FILE:是否存在并且为目录文件;
-f FILE:是否存在并且为普通文件;
-h FILE 或 -L FILE:是否存在并且为符号链接文件;
-p FILE:是否存在并且为管道文件;
-S FILE:是否存在并且为套接字文件;
文件权限测试:
-r FILE:是否存在并且对当前用户可读;
-w FILE:是否存在并且对当前用户可写;
-x FILE:是否存在并且对当前用户可执行;
特殊权限测试:
-u FILE:是否存在并且拥有suid权限;
-g FILE:是否存在并且拥有sgid权限;
-k FILE:是否存在并且拥有sticky权限;
注意:对于脚本则是当前运行此脚本的用户
文件是否有内容:
-s FILE:是否有内容;
时间戳测试:
-N FILE:文件自从上一次读取操作后是否被修改过
从属关系测试:
-O FILE:当前用户是否为文件的属主;
-G FILE:当前用户是否属于文件的属组;
双目测试:
FILE 1 -ef FILE2 :FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;
FILE 1 -nt FILE2 :FILE1的最近一次更新时间是否新于FILE2的最近一次更新时间
FILE 1 -ot FILE2 :FILE1的最近一次更新时间是否旧于FILE2的最近一次更新时间
组合测试条件:
逻辑运算:
第一种方式:
COMMAND1 && COMMAND2
COMMAND1 || COMMAND2
! COMMAND
eg: [ -O FILE ] && [ -r FILE ]
第二种方式:
test EXPRESSION1 -a EXPRESSION2
[ EXPRESSION1 -a EXPRESSION2 ]
[[ EXPRESSION1 -a EXPRESSION2 ]]
类此还有
EXPRESSION1 -o EXPRESSION2
! EXPRESSION
eg:[ -O FILE -a -r FILE ]
注意:模式匹配时,势必要激活正则表达式引擎,而使用正则表达式的测试判断,要比单一字符串测试判断要慢,所以尽量避免使用正则表达式进行查找比较和测试;
脚本的状态返回值:
默认是脚本中执行的最后一条件命令的状态返回值
自定义状态退出状态码:exit [n]:n为自己指定的状态码;
注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;
三、bash脚本语句
过程式编程语言的代码执行顺序:
顺序执行:从左至右,从上至下,逐一运行
选择执行:代码有一个分支:条件满足时才会执行
两个或以上的分支:只会执行其中一个满足条件的分支
循环执行:
代码片段(循环体)要执行0、1或多次重复运行
选择执行:
单分支的if语句
if 测试条件;then
代码分支
条件为真则执行,为假则不执行
或者
fi
if 测试条件
then
代码分支
条件为真则执行,为假则不执行 fi
双分支的if语句:
if 测试条件;then
条件为真时执行的分支
else
条件为假时执行的分支
fi
多分支的if语句:
if COMDITION1;then
条件1为真分支
elif COMDITION2;then
条件2为真分支
elif COMDITION3;then
条件3为真分支
…
elif COMDITIONn;then
条件n为真分支
else
所有条件均不满足时的分支
fi
注意:即便多个条件可能同时都能满足,分支只会执行其中一个,首先测试为“真”;并且if语句可嵌套if等其他语句
case语句的语法格式:
case $VARAIBLE in
PATH1)
分支
;;
PATH2)
分支
;;
…
*)
分支
;;
esac
注意:双分号如果不加,则会前一个匹配执行后,下一个会接着匹配执行
适用于一个变量,与多个可能取值比较
支持glob风格的通配符:
*:任意长度的任意字符;
?:任意单个字符
[]:范围内任意个字符
a|b:a或b;
bash脚本编程之用户交互:
脚本参数
用户交互:通过键盘输入数据,从而完成变量赋值操作
read [option]…[name…]
-p ‘PROMPT’ 提示注释信息
-t TIMEOUT 时间限制
bash -n /path/to/some_script
检测脚本中的语法错误
bash -x /path/to/some_script
调试执行
循环执行:将一段代码重复执行0、1或多次;
进入条件:条件满足时才进入循环
退出条件:每一个循环都应该有退出条件,以有机会退出循环
bash脚本:
for循环
while循环
until循环
for循环:
执行机制:依次将列表中的元素赋值给“变量名” ; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
两种格式:
(1)遍历列表
(2)控制变量
遍历列表
for VARAIBLE in LIST;do
循环体
done
进入条件:LIST列表有元素,即可进入循环
退出条件:列表中的元素遍历完成
LIST的生成方式:
(1)直接给出;
(2)整数列表
(a){start…end}
(b)seq [start [incremtal]] last
(3)返回列表的命令:$(COMMAND),例如:ls cat
(4)glob通配符
(5)变量引用;例如$@,$*
格式示例:
#!/bin/bash
#
for username in user1 user2 user3;do
if id $username &>/dev/null;then
echo “$username exists.”
else
useradd $username && echo “Add user $username finished.”
fi
done
示例:求100以内的正整数之和
#!/bin/bash
#
delcare -i sum=0
for i in {1..100};do
echo “\$sum is $sum,\$i is $i”
sum=$[$sum+$i]
done
echo $sum
示例:判断/var/logm目录下的每一个文件的内容类型
#!/bin/bash
#
for filename in /var/log/*;do
if [ -f $filename ];then
echo “Common file.”
elif [ -L $filename ];then
echo “Sysbolic link”
elif [ -d $filename ];then
echo “Directory.”
elif [ -b $filename ];then
echo “block special file.”
elif [ -c $filename ];then
echo “character special file.”
elif [ -S $filename ];then
echo “Socket file.”
else
echo “Unkown.”
fi
done
while循环:
while CONDITION;do
循环体
循环控制变量修正表达式
done
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION测试为“真”
退出条件:CONDITION测试为“假”
示例:求100以内的正整数之和
#!/bin/bash
#
declare -i sum=0
declare -i i=1
while [ $i -le 100 ];do
sum=$[$sum+$i]
let i++
done
echo $sum
原创文章,作者:cnc,如若转载,请注明出处:http://www.178linux.com/71736