【条件判断】
1. 按文件类型进行判断
-b 文件 判断该文件是否存在,并且为块设备文件(是块设备文件为真)
-c 文件 判断该文件是否存在,并且为字符设备文件(是字符设备文件为真)
-d 文件 判断该文件是否存在,并且为目录文件(是目录为真)
-e 文件 判断该文件是否存在(存在为真)
-f 文件 判断该文件是否存在,并且为普通文件(是普通文件为真)
-L 文件 判断该文件是否存在,并且为符号链接文件(是符号链接文件为真)
-p 文件 判断该文件是否存在,并且为管道文件(是管道文件为真)
-s 文件 判断该文件是否存在,并且为非空(非空为真)
-S 文件 判断该文件是否存在,并且为套接字文件(是套接字文件为真)
两种判断格式:
① test -e /root/install.log
② [ -e /root/install.log ]
[ -f /root/install.log ] && echo 'yes' || echo 'no'
2. 按照文件权限进行判断(不区分所有者, 所属组)
-r 文件 判断该文件是否存在,并且拥有读权限(有读权限为真)
-w 文件 判断该文件是否存在,并且拥有写权限(有写权限为真)
-x 文件 判断该文件是否存在,并且拥有执行权限(有执行权限为真)
-u 文件 判断该文件是否存在,并且拥有SUID权限(有SUID权限为真)
-g 文件 判断该文件是否存在,并且拥有SGID权限(有SGID权限为真)
-k 文件 判断该文件是否存在,并且拥有SBit权限(有SBit权限为真)
3. 两个文件之间进行比较
文件1 -nt 文件2 判断文件1的修改时间是否比文件2的新(如果新则为真)
文件1 -ot 文件2 判断文件1的修改 时间是否比文件2的旧
文件1 -ef 文件2 判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法。
4. 两个整数之间比较
整数1 -eq 整数2 判断整数1是否和整数2相等(相等为真)
整数1 -ne 整数2 判断整数1是否和整数2不相等(不相等为真)
整数1 -gt 整数2 判断整数1是否大于整数2(大于为真)
整数1 -lt 整数2 判断整数1是否大于整数2(小于为真)
整数1 -ge 整数2 判断整数1是否大于等于整数2(大于等于为真)
整数1 -le 整数2 判断整数1是否小于等于整数2(小于等于为真)
[ 1 eq 2 ] && echo 'yes' || echo 'no'
5. 字符串的判断
-z 字符串 判断字符串是否为空(为空返回真)
-n 字符串 判断字符串是否为非空(非空返回真)
字符串1 == 字符串2 判断字符串1和字符串2是否相等(相等返回真)
字符串1 != 字符串2 判断字符串1是否和字符串2不相等(不相等返回真)
name=chen
[ -z "$name" ] && echo 'yes' || echo 'no'
6. 多重条件判断
判断1 -a 判断2 逻辑与,判断1和判断2都成立,最终的结果才为真
判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,最终的结果就为真
! 判断 逻辑非,使原始的判断式取反
a=24
[ -n "$a" -a "$a" -gt 23 ] && echo 'yes' || echo 'no'
【流程控制 - if 语句】
1. 单分支if条件语句
if [ 条件判断式 ]; then 程序 fi
if test -z "$ac_version"; then 程序 fi
或者
if [ 条件判断式 ] then 程序 fi
注意:
① if开头,fi结尾
② [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
③ then后面跟符合条件之后执行的程序,可以放在[]之后,用" ; "分割,也可以换行写入,就不需要" ; "了。
#!/bin/bash # 统计根分区使用率 rate=$(df -h | grep "/dev/sda3" | awk '{print $5}' | cut -d "%" -f1) # 把根分区使用率作为变量值赋予变量rate if [ $rate -ge 80 ]; then echo "Warning! /dev/sda3 is full !" fi
2. 双分支if条件语句
if [ 条件判断式 ] then 条件成立时,执行的程序 else 条件不成立时,执行的另一个程序 fi
#!/bin/bash # 备份mysql数据库 ntpdate asia.pool.ntp.org &> /dev/null # 同步系统时间(需联网) date=$(date +%y%m%d) # 把当前系统时间按照"年月日"格式赋予变量date size=$(du -sh /var/lib/mysql) # 统计mysql数据库的大小,并把大小赋予size变量 if [ -d /tmp/dbbak ] then echo "Date: $date!" > /tmp/dbbak/dbinfo.txt
echo "Data size: $size" >> /tmp/dbbak/dbinfo.txt
cd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt
&> /dev/null # 把所有输出丢弃
rm -rf /tmp/dbbak/dbinfo.txt # 卸磨杀驴 else mkdir /tmp/dbbak ... fi
#!/bin/bash # 判断Apache是否启动 ( 先安装nmap:rpm -ivh http://nmap.org/dist/nmap-4.68-1.i386.rpm ) port=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk '{print $2}') # 使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port
if [ "$port" == "open" ] then echo "$(date) httpd is ok!" >> /tmp/httpd-acc.log # 如果状态正常,追加到日志中 else /etc/rc.d/init.d/httpd start &> /dev/null # 把所有输出丢弃 echo "$(date) httpd reboot!" >> /tmp/httpd-err.log # 重启记录追加到错误日志 fi
3. 多分支if条件语句
if [ 条件判断式1 ] then 当条件判断式1成立时,执行程序1 elif [ 条件判断式2 ] then 当条件判断式2成立时,执行程序2 ...更多判断... else 当所有条件都不成立时,最后执行此程序 fi
#!/bin/bash # 判断用户输入的是什么文件 read -p "Please input a filename:" file # 接收键盘的输入,并赋予变量file if [ -z "$file" ] then echo "Error, please input a filename" exit 1 elif [ ! -e "$file" ] # 判断file的值是否存在 then echo "Your input is not a file!" exit 2 elif [ -f "$file" ] # 判断file的值是否为普通文件 then echo "$file is a regular fie!" elif [ -d "$file" ] then echo "$file is a directory!" else echo "$file is an other file!" fi
【流程控制 - case 语句】
多分支case条件语句:case语句只能判断一种条件关系,而if语句可以判断多种条件关系。
case $变量名 in "值1") 如果变量的值等于值1,则执行程序1 ;; "值2")
如果变量的值等于值2,则执行程序2 ;; *) 如果变量的值都不是以上的值,则执行此程序 ;; esac
#!/bin/bash # 判断用户输入
read -p "Please choose yes/no" -t 30 cho case $cho in "yes") echo "You choose yes" ;; "no") echo "You choose no" ;; *) echo "You choose none" ;; esac
【流程控制 - for 循环】
语法1:
for 变量 in 值1 值2 值3... ; do 程序 done
语法2:
for (( 初始值; 循环控制条件; 变量变化 )) do 程序 done
#!/bin/bash # 打印时间
for time in morning noon afternoon evening ; do echo "This time is $time" done for i in 1 2 3 4 ; do echo $i done
#!/bin/bash # 批量解压缩脚本 cd /lnmp ls *.tar.gz > ls.log for i in $(cat ls.log) ; do tar -zxf $i &> /dev/null done rm -rf /lnmp/ls.log
#!/bin/bash # 求和 s=0 for (( i=1; i<=100; i++ )) ; do s=$(( $s + $i )) done
echo "The sum of 1+2+3+...+100 is : $s"
#!/bin/bash # 批量添加指定数量的用户 read -p "Please input user name:" -t 30 name read -p "Please input the number of users:" -t 30 num read -p "Please input the password of users:" -t 30 pass # -a用于连续多个条件判断 if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ] then y=$(echo $num | sed 's/^[0-9]*$//g') # 任意数字替换为空 if [ -z "$y" ] # 如果y的值是空,则num是数字 then for (( i=0; i<=$num; i++ )) do /usr/sbin/useradd $name$i &> /dev/null echo $pass | /usr/bin/passwd --stdin "$name$i" &> /dev/null done fi fi
【流程控制 - while 和 until 循环】
while循环是条件循环,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。
while [ 条件判断式 ] do 程序 done
#!/bin/bash # 示例用法 while [ $# -gt 0 ]; do case "$#" in 3) echo "第一个参数是$1, 参数个数是$#" ;; 4) echo "第一个参数是$1, 参数个数是$#" ;; *) echo 'What happened' ;; esac # 与case对应构成case语句,形如if和fi case "$#" in abc) ... ;; esac shift # 用shift命令把位置参数左移 done
运行如:./example.sh 3 4 5
until循环:和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
#!/bin/bash i=1 s=0 until [ "$i" -gt 100 ] # 循环直到变量i的值大于100就停止循环 do s=$(( $i + $s)) i=$(( $i + 1 )) done
echo "The sum is : $i"
【总结】
Shell适用:帮助管理员减少重复操作或进行运维操作,不适合进行复杂的运算的场合。
如何建立编程思想:学习,练习,知道让程序帮你干什么。