首页 > 代码库 > shell脚本编程之基础篇(二)
shell脚本编程之基础篇(二)
shell脚本编程之基础篇(二)
==============================================================================
概述:
==============================================================================
退出状态
★进程使用退出状态来报告成功或失败
◆0 代表成功,1-255代表失败
◆$? 变量保存最近的命令退出状态 (查看:echo $?)存的是最后一条命令的结果,中间即使有错误,也不管。
★脚本的状态返回值
◆默认是脚本中执行的最后一条命令的状态返回值;
◆自定义状态退出状态码;
exit[n]:自定义退出状态码;(exit退出的是当前shell)
注意:
脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
演示:
1.进程使用退出状态
-c1代表一个数据包,-W代表一秒钟 [root@centos7 ~]# ping -c1 -W1 192.168.1.116 &> /devnull [root@centos7 ~]# echo $? 0 # 成功,此主机正在使用 [root@centos7 ~]# ping -c1 -W1 192.168.1.112 &> /devnull [root@centos7 ~]# echo $? 1 # 失败,此主机没有使用
条件测试
★作用:
判断某需求是否满足,需要由测试机制来实现;
专用的测试表达式需要由测试命令辅助完成测试过程;
★如何编写测试表达式以实现所需的测试:
☉执行命令,并利用状态返回值来判断:
0:成功
1-255:失败
☉测试表达式:
test EXPRESSION;
[ EXPRESSION ];
[[ EXPRESSION ]];特定情况下使用。最稳妥(支持正则表达式)
注意:
EXPRESSION前后必须有空白字符,否则语法错误。
★条件性的执行操作符
☉根据退出状态而定,命令可以有条件地运行
&& :代表条件性的AND THEN;
|| :代表条件性的OR ELSE
演示:
[root@centos7 ~]# ping -c1 -W1 192.168.1.1 &> /dev/null && echo "The host is up" The host is up # 表示 如果能 ping 通这个主机 就输出 up,不能就输出 down;一定是先与后或 [root@centos7 ~]# ping -c1 -W1 192.168.1.1 &> /dev/null && echo "The host is up" || echo "The host is down" The host is up [root@centos7 ~]# ping -c1 -W1 192.168.1.114 &> /dev/null && echo "The host is up" || echo "The host is down" The host is down # 表示 如果能 ping 通这个主机 就输出 up,不能就输出 down,且返回值为 220。这里的括号表示在子shell中执行 [root@centos7 ~]# ping -c1 -W1 192.168.1.114 &> /dev/null && echo "The host is up" || (echo "The host is down" ;exit 220) The host is down [root@centos7 ~]# echo $? 220
bash的测试类型(数值,字符串,文件测试)
1.数值测试
★数值测试
☉作用:数值比较
☉操作符
-eq:是否等于;[ $num1 -eq $num2 ];
-ne:是否不等于;
-gt:是否大于;
-ge:是否大于等于;
-lt:是否小于;
-le:是否小于等于;
演示:
[root@centos7 ~]# test 2 -eq 3 [root@centos7 ~]# echo $? 1 [root@centos7 ~]# test 2 -ne 3 [root@centos7 ~]# echo $? 0 [root@centos7 ~]# test 2 -gt 3 [root@centos7 ~]# echo $? 1 [root@centos7 ~]# test 2 -lt 3 [root@centos7 ~]# echo $? 0
2.字符串测试
★字符串测试
字符串比较要加引号;
尽量要使用[[ ]]
☉操作符
==:是否等于;
>:ascii码是否大于ascii码;
<:ascii码是否小于ascii码
!=:是否不等于;
=~:左侧字符串是否能够被右侧的PATTERN所匹配(扩展表达式)
-z "STRING":判断指定的字符串是否为空,空为真,不空为假;
-n "STRING":判断指定的字符串是否不空,不空为真,空为假;
注意:
字符串比较要加引号,表示引用,做变量替换要加双引号,不做变量替换用单引号;
要尽量使用 [[ ]]
演示:
[root@centos7 ~]# [ tom == Tom ] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [ tom == tom ] [root@centos7 ~]# echo $? 0 # 变量替换要尽量用双引号,如果不用的话,如果变量不存在为空,会报错 [root@centos7 ~]# [ tom == $name ] -bash: [: tom: 期待一元表达式 [root@centos7 ~]# [ tom == "$name" ] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# name=xiu [root@centos7 ~]# [ tom == $name ] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [ tom == "$name" ] [root@centos7 ~]# echo $? 1 # 要尽量使用 [[ ]] [root@centos7 ~]# [ ‘a‘ > ‘b‘ ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ ‘a‘ < ‘b‘ ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [[ ‘a‘ > ‘b‘ ]] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [[ ‘a‘ < ‘b‘ ]] [root@centos7 ~]# echo $? 0 #============================================================================ [root@centos7 ~]# name=haha [root@centos7 ~]# echo $name haha [root@centos7 ~]# [[ "$name" =~ ha ]] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [[ "$name" =~ h ]] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [[ "$name" =~ hx ]] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [[ "$name" =~ xx ]] [root@centos7 ~]# echo $? 1 # 是否为空 [root@centos7 ~]# [[ -z "$name" ]] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [[ -n "$name" ]] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [[ -z "$tao" ]] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [[ -n "$tao" ]] [root@centos7 ~]# echo $? 1
3.文件测试
★存在性测试
-a FILE:同-e
-e FILE:文件存在性测试,存在为真,否则为假;
★存在性及类型测试
-b FILE:是否存在且为块设备文件;
-c FILE:是否存在且为字符设备文件;
-d FILE:是否存在且为目录文件;
-f FILE:是否存在且为普通文件;
-h FILE 或-L FILE:存在且为符号链接文件;
-p FILE:是否存在且为命名管道文件;
-S FILE:是否存在且为套接字文件;
★文件权限测试
-r FILE:是否存在且对当前用户可读;
-w FILE:是否存在且对当前用户可写;
-x FILE:是否存在且对当前用户可执行
★文件特殊权限测试
-g FILE:是否存在且拥有sgid权限;
-u FILE:是否存在且拥有suid权限;
-k FILE:是否存在且拥有sticky权限;
★文件是否有内容
-s FILE:是否存在且非空(即,文件是否有内容);
★文件时间戳测试
-N FILE:文件自从上一次读操作后是否被修改过;
★从属关系测试
-O FILE:当前用户是否为文件的属主;
-G FILE:当前用户是否属于文件的属组;
★文件是否打开
-t fd:fd表示文件描述符是否已经打开且与某终端相关;
★双目测试
FILE1 -ef FILE2:FILE1与FILE2是否指向同一个设备上的相同inode;
FILE1 -nt FILE2:FILE1是否新于FILE2;(修改时间)
FILE1 -ot FILE2:FILE1是否旧于FILE2;
注意:
文件测试一般使用 [ ] 就可以
演示:
1.文件存在性测试
[root@centos7 ~]# [ -e /etc/fstab ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ -e /etc/rc.d/rc.sysinit ] [root@centos7 ~]# echo $? 1
2.文件存在性及类型测试
[root@centos7 ~]# [ -b /dev/sda ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ -b /dev/sdb ] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [ -d /etc ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ -L /etc/redhat-release ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# ll /etc/redhat-release lrwxrwxrwx. 1 root root 14 11月 6 18:30 /etc/redhat-release -> centos-release
3.文件权限及特殊权限测试
[root@centos7 ~]# ll /etc/shadow ---------- 1 root root 1400 2月 20 14:12 /etc/shadow [centos@centos7 ~]$ whoami centos [centos@centos7 ~]$ [ -r /etc/shadow ] [centos@centos7 ~]$ echo $? 1 [centos@centos7 ~]$ [ -r /etc/passwd ] [centos@centos7 ~]$ echo $? 0 [centos@centos7 ~]$ [ -w /etc/passwd ] [centos@centos7 ~]$ echo $? 1 # 对于root用户来讲,rw 权限是以实际为主,但执行权限是起作用的 [root@centos7 ~]# whoami root [root@centos7 ~]# [ -r /etc/shadow ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ -w /etc/shadow ] [root@centos7 ~]# echo $? 0 [root@centos7 ~]# [ -x /etc/shadow ] [root@centos7 ~]# echo $? 1 #========================================================================== [root@centos7 ~]# [ -u /usr/bin/passwd ] [root@centos7 ~]# echo $? 0 # 说明 /usr/bin/passwd 拥有suid权限 [root@centos7 ~]# ll /usr/bin/passwd -rwsr-xr-x. 1 root root 27832 6月 10 2014 /usr/bin/passwd
4.文件是否有内容测试
[root@centos7 ~]# touch /tmp/hello [root@centos7 ~]# [ -s /tmp/hello ] [root@centos7 ~]# echo $? 1 [root@centos7 ~]# [ -s /etc/fstab ] [root@centos7 ~]# echo $? 0
5.双目测试
[root@centos7 ~]# touch f1 [root@centos7 ~]# ln f1 f22 # 创建f22 的硬链接为f1 [root@centos7 ~]# [ f1 -ef f22 ] # 是否指向同一设备上相同的inode,也就是说是否为硬链接 [root@centos7 ~]# echo $? 0 [root@centos7 ~]# ll -i f1 f22 201391291 -rw-r--r-- 2 root root 1024 2月 23 18:39 f1 201391291 -rw-r--r-- 2 root root 1024 2月 23 18:39 f22
4.组合测试条件
★第一种方式
OMMAND1 && COMMAND2 :并且;
COMMAND1 || COMMAND2 :或者;
!COMMAND :非
示例:
[ -O FILE ] && [ -r FILE ]
★第二种方式
EXPRESSION1 -a EXPRESSION2 :并且
EXPRESSION1 -o EXPRESSION2 :或者
! EXPRESSION:取反
注意:
使用[ ],[[ ]]或者 test
示例:
[ -O FILE -a -r FILE ]
练习:
1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小。
[root@centos7 bin]# cat systeminfo.sh #!/bin/bash # 取 IP 地址,采用sed方法,掐头去尾 server_ip=$(ifconfig |sed -n ‘2p‘ |sed -e ‘s@^.*inet@@‘ -e ‘s@net.*@@‘) CPUmod=$(lscpu | grep -i "model name:") Meninfo=$(free -h | sed -n ‘2p‘ | tr -s ‘ ‘ | cut -d‘ ‘ -f2) DISKinfo=$(fdisk -l |grep "Disk /dev/[sh]d[a-z]" |sed -r ‘s@.* ([0-9]+.*GB).*@\1@‘) echo ‘hostname :‘$(hostname) echo ‘hostIP:‘$server_ip echo ‘OS version:‘$(cat /etc/redhat-release) echo ‘Kernel version:‘$(uname -r) echo ‘CPU ‘$CPUmod echo ‘Memory :‘$Meninfo echo ‘Harddisk:‘$DISKinfo # 执行脚本 [root@centos7 bin]# chmod +x systeminfo.sh [root@centos7 bin]# ll systeminfo.sh -rwxr-xr-x 1 root root 522 Feb 23 21:42 systeminfo.sh [root@centos7 bin]# cd [root@centos7 ~]# systeminfo.sh hostname :centos7 hostIP: 192.168.1.112 OS version:CentOS Linux release 7.2.1511 (Core) Kernel version:3.10.0-327.el7.x86_64 CPU Model name: Intel(R) Core(TM) i3-2328M CPU @ 2.20GHz Memory :977M Harddisk:85.9 GB
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序
5、写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和
6、写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
7、写一个脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
8、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
9、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”
10、chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件是否不可读且不可写
11、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统。
12、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,先判断是否合格IP,否,提示IP格式不合法,并退出,是,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”
13、计算1+2+3+4+...+100的值
14、计算从脚本的第一个参数A开始,到第二个参数B的所有数字的总和,判断B是否大于A,是计算,否提示错误并退出。
本文出自 “逐梦小涛” 博客,请务必保留此出处http://1992tao.blog.51cto.com/11606804/1900708
shell脚本编程之基础篇(二)