bash脚本编程
- 脚本文件格式:
#!/bin/bash
#description:xxxx
#version:1.0
#author:xxx@xx.xx
#last date:xxxx.xx.xx
第一行,顶格:#!/bin/bash
注释信息:#
代码注释:
缩进,适度添加空白行;
语言:编程语法格式,库,算法和数据结构
编程思想:
问题空间 --> 解空间变量:
局部变量
本地变量
环境变量
位置参数变量
特殊变量数据类型:字符型、数值型
弱类型:字符型算术运算:
+, -, *, /, %, **
let VAR=expression
VAR=$[expression]
VAR=$((expression))
VAR=$(expr argu1 argu2 argu3)
注意:有些时候乘法符号需要转义;
-
增强型赋值:
变量做某种算术运算后回存至此变量中;
let i=$i+#
let i+=#+=,-=,*=, /=, %= 自增: VAR=$[$VAR+1] let VAR+=1 let VAR++ 自减: VAR=$[$VAR-1] let VAR-=1 let VAR--
练习:
1、写一个脚本
计算/etc/passwd文件中的第10个用户和第20个用户的id号之和;
[root@localhost ~]# bash /tmp/myadd.sh
11
[root@localhost ~]# cat /tmp/myadd.sh
#!/bin/bash
id1=$(head -1 /etc/passwd|tail -1 |cut -d: -f3)
id2=$(head -10 /etc/passwd|tail -1 |cut -d: -f3)
id_sum=$[$id1+$id2]
echo $id_sum
2、写一个脚本
计算/etc/rc.d/init.d/functions和/etc/inittab文件的空白行数之和;
[root@localhost ~]# bash /tmp/mycount.sh
91
[root@localhost ~]# cat /tmp/mycount.sh
#!/bin/bash
file1=/etc/rc.d/init.d/functions
file2=/etc/inittab
blank1=`grep '^[[:space:]]*$' $file1 |wc -l`
blank2=`grep '^[[:space:]]*$' $file2 |wc -l`
bsum=$[$blank1+$blank2]
echo $bsum
条件测试:
判断某需求是否满足,需要由测试机制来实现;
如何编写测试表达式以实现所需的测试:
- 执行命令,并利用命令状态返回值来判断;
0:成功
1-255:失败
- 测试表达式
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION两端必须有空白字符,否则为语法错误
bash的测试类型:
数值测试
字符串测试
文件测试
数值测试:数值比较
-eq:是否等于 [ $num1 -eq $num2 ]
-ne:是否不等于
-gt:是否大于
-ge:是否大于等于
-lt:是否小于
-le:是否小于等于
字符串测试:
==:是否等于
>:是否大于
<:是否小于
!=:是否不等于
=~:左侧字符串是否能够被右侧的PATTERN所匹配
-z "STRING":判断指定的字串是否为空;空则为真,不空则假
-n "STRING":判断指定的字符串是否不空;不空则真,空则为假
注意:
1.字符串要加引用
2.要使用[[ ]]
文件测试:
存在性测试
-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:当前用户是否属于文件的属组
双目测试:
FILE1 -ef FILE2:FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接
FILE1 -nt FILE2:FILE1是否新于FILE2
FILE1 -ot FILE2:FILE1是否旧于FILE2
-
组合测试条件:
逻辑运算:
第一种方式:
COMMAND1 && COMMAND2
COMMAND1 || COMMAND2
! COMMAND
e.g.
[ -O FILE ] && [ -r FILE ]
第二种方式:
EXPRESSION1 -a EXPRESSION2
EXPRESSION1 -o EXPRESSION2
! EXPRESSION
e.g.
[ -O FILE -a -x FILE ]
脚本的状态返回值:
- 默认是脚本中执行的最后一条件命令的状态返回值;
- 自定义状态退出状态码:
exit [n]:n为自己指定的状态码
注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;
练习:
将当前主机名称保存至hostName变量中;
主机名如果为空,或者为localhost.localdomain,则将其设置为www.xxx.com;
[root@localhost ~]# cat /scripts/judge.sh
hostName=`hostname`
[ -z "$hostName" -o "$hostName" == "localhost.localdomain" ] && hostname -b www.xxx.com