一、Shell 条件判断有哪些基础形式¶
原笔记给出的核心判断形式有 4 种:
test[ ][[ ]](( ))
其中最常用的是前两种,区别需要记住:
[ ]和test更适合普通判断[[ ]]更适合做正则匹配(( ))更适合做整数运算判断
二、文件判断是运维脚本的基本功¶
原笔记列出的常用文件判断条件如下:
-f:是否为普通文件-d:是否为目录-x:是否有执行权限-s:文件是否非空-r:是否可读-w:是否可写-L:是否为软链接-e:是否存在
例如:
[ -f /etc/hosts ] && echo "成立" || echo "失败"
[ -d /etc ] && echo "成立" || echo "失败"
[ -x /etc/rc.d/rc.local ] && echo "成立" || echo "失败"
[ -s /etc/hosts ] && echo "成立" || echo "失败"
原笔记也提醒了一个很细但很重要的点:[ 和条件之间必须保留空格。
三、字符串比较最常见的几种写法¶
Shell 脚本里处理字符串时,最常见的是下面这些判断:
=:相等!=:不相等-z:字符串为空-n:字符串非空
例如:
input=start
[ "$input" = "start" ] && echo "成立" || echo "失败"
unset str2
[ -z "$str2" ] && echo "变量为空" || echo "变量非空"
[ -n "$str2" ] && echo "变量非空" || echo "变量为空"
原笔记还提到一个企业里常见的小技巧:比较时可以给变量尾部补一个 x,减少空值引起的歧义。
[ "${str1}x" = "${str2}x" ] && echo "成立" || echo "失败"
四、整数比较和逻辑判断怎么写¶
整数比较最常见的关键字有:
-eq:等于-ne:不等于-gt:大于-ge:大于等于-lt:小于-le:小于等于
示例:
[ 666 -gt 1 ] && echo "成立" || echo "失败"
[ 6 -eq 6 ] && echo "成立" || echo "失败"
多条件判断时:
[ ]里常用-a、-o、![[ ]]里常用&&、||、!
[ "$sex" = "nv" -a "$guo" = "china" ] && echo "肯定能成" || echo "还需努力"
[ "$sex" = "nv" -o "$guo" = "china" ] && echo "成立" || echo "失败"
五、正则判断要优先使用 [[ ]]¶
原笔记给出的典型示例是判断变量里是否为数字:
[[ $num =~ ^[0-9]+$ ]] && echo "成立" || echo "失败"
[[ $num1 =~ ^-?[0-9]+$ ]]
如果要支持负数,可以在开头补 -?;如果还想兼容小数,则可以扩展为更复杂的模式。
六、if 比 && 和 || 更适合复杂逻辑¶
当逻辑稍微复杂一点时,就该切换到 if。
6.1 单分支判断¶
if [ $# -ne 2 ]; then
echo "脚本必须要2个参数"
exit 1
fi
这类写法非常适合放在脚本开头做参数检查。
6.2 双分支判断¶
原笔记用根分区磁盘使用率做了示例:
#!/bin/bash
root_usage=$(df -h | grep -w '/' | awk -F'[ %]+' '{print $(NF-1)}')
if [ $root_usage -ge 80 ]; then
echo "磁盘空间不足,请尽快处理"
else
echo "磁盘空间正常"
fi
6.3 多分支判断¶
原笔记把“比较两个数字大小”改造成了多分支版:
#!/bin/bash
read -p "请输入两个数字:num1 num2" num1 num2
[[ $num1 =~ ^-?[0-9]+$ ]] || { echo "$num1必须是数字"; exit 1; }
[[ $num2 =~ ^-?[0-9]+$ ]] || { echo "$num2必须是数字"; exit 1; }
if [ $num1 -eq $num2 ]; then
echo "$num1 == $num2"
elif [ $num1 -gt $num2 ]; then
echo "$num1 > $num2"
else
echo "$num1 < $num2"
fi
七、实战:输出指定用户的信息¶
这是原笔记里非常像企业巡检脚本的一个案例,逻辑很完整:
1、接收用户名,没有传参时默认检查 root
2、判断用户是否存在
3、如果存在,则输出 uid、gid、家目录、Shell 和最近登录信息
可整理为:
#!/bin/bash
user=${1:-root}
id $user &>/dev/null
[ $? -ne 0 ] && {
echo "用户不存在"
exit 1
}
user_shell=$(grep "^${user}:" /etc/passwd | awk -F: '{print $NF}')
if [ "$user_shell" = "/bin/bash" ]; then
user_login="可以登录"
else
user_login="不可以登录"
fi
user_uid=$(grep "^${user}:" /etc/passwd | awk -F: '{print $3}')
user_gid=$(grep "^${user}:" /etc/passwd | awk -F: '{print $4}')
user_homedir=$(grep "^${user}:" /etc/passwd | awk -F: '{print $(NF-1)}')
user_lastlog=$(lastlog | grep -w "${user}")
cat <<EOF
#########################################
用户名: ${user}
用户uid: ${user_uid}
用户gid: ${user_gid}
用户是否可以登录: ${user_login}
用户家目录: ${user_homedir}
用户最后一次登录情况: ${user_lastlog}
#########################################
EOF
这个例子很好地说明:条件判断并不是为了“语法题”,而是为了把系统信息转成可靠的运维输出。
八、条件判断这一章要重点记住什么¶
原笔记最后的小结可以压缩成下面几条:
- 文件判断:重点记
-f、-d、-x、-s - 字符串判断:重点记
=、!=、-z、-n - 整数判断:重点记
-eq、-ne、-gt、-ge、-lt、-le - 逻辑判断:会用
-a、-o、! - 正则判断:优先用
[[ $var =~ regex ]]
只要把这套判断体系练熟,Shell 自动化脚本就从“命令堆砌”真正进入“有逻辑的程序”。