逻辑运算符 #
一、逻辑运算符概述 #
1.1 基本逻辑运算符 #
| 运算符 | 说明 | 示例 |
|---|---|---|
| && | 逻辑与 | [[ $a -gt 0 && $b -gt 0 ]] |
| || | 逻辑或 | [[ $a -gt 0 || $b -gt 0 ]] |
| ! | 逻辑非 | [[ ! $a -eq 0 ]] |
1.2 命令连接符 #
| 运算符 | 说明 | 示例 |
|---|---|---|
| && | 前面成功才执行后面 | cmd1 && cmd2 |
| || | 前面失败才执行后面 | cmd1 || cmd2 |
| ; | 顺序执行 | cmd1 ; cmd2 |
二、逻辑与 (&&) #
2.1 条件判断中使用 #
bash
#!/bin/bash
a=10
b=5
# 在 [[ ]] 中使用
if [[ $a -gt 0 && $b -gt 0 ]]; then
echo "a和b都大于0"
fi
# 在 (( )) 中使用
if (( a > 0 && b > 0 )); then
echo "a和b都大于0"
fi
# 多个条件
if [[ $a -gt 0 && $a -lt 20 && $b -gt 0 ]]; then
echo "所有条件都满足"
fi
2.2 命令连接中使用 #
bash
#!/bin/bash
# 前面命令成功才执行后面
mkdir /tmp/test && echo "目录创建成功"
# 链式执行
cd /tmp && mkdir test && cd test && echo "操作成功"
# 实际应用
ping -c 1 google.com && echo "网络正常" || echo "网络异常"
# 检查文件并执行操作
[ -f config.sh ] && source config.sh
2.3 短路求值 #
bash
#!/bin/bash
# && 的短路特性:前面为假,后面不执行
false && echo "这行不会执行"
true && echo "这行会执行"
# 利用短路特性设置默认值
name=""
[ -z "$name" ] && name="默认用户"
echo "用户名: $name"
# 条件赋值
[ -f config.env ] && source config.env
三、逻辑或 (||) #
3.1 条件判断中使用 #
bash
#!/bin/bash
a=10
b=-5
# 在 [[ ]] 中使用
if [[ $a -gt 0 || $b -gt 0 ]]; then
echo "a或b至少有一个大于0"
fi
# 在 (( )) 中使用
if (( a > 0 || b > 0 )); then
echo "a或b至少有一个大于0"
fi
# 多个条件
if [[ $a -gt 0 || $a -lt -10 || $b -gt 0 ]]; then
echo "至少有一个条件满足"
fi
3.2 命令连接中使用 #
bash
#!/bin/bash
# 前面命令失败才执行后面
mkdir /tmp/test || echo "目录可能已存在"
# 默认值设置
config_file="${1:-default.conf}"
# 错误处理
cd /nonexistent || { echo "目录不存在"; exit 1; }
# 备用方案
command -v vim >/dev/null || alias vim=vi
# 检查依赖
command -v git >/dev/null || { echo "需要安装git"; exit 1; }
3.3 短路求值 #
bash
#!/bin/bash
# || 的短路特性:前面为真,后面不执行
true || echo "这行不会执行"
false || echo "这行会执行"
# 利用短路特性提供默认值
file="${1:-}"
[ -n "$file" ] || file="default.txt"
echo "使用文件: $file"
# 错误处理
cp important.txt backup.txt || { echo "备份失败"; exit 1; }
四、逻辑非 (!) #
4.1 条件取反 #
bash
#!/bin/bash
a=0
# 取反
if [[ ! $a -eq 0 ]]; then
echo "a不等于0"
fi
# 检查文件不存在
if [[ ! -f "/tmp/test" ]]; then
echo "文件不存在"
fi
# 检查目录不存在
if [[ ! -d "/tmp/testdir" ]]; then
mkdir -p /tmp/testdir
fi
# 检查变量为空
if [[ ! -n "$var" ]]; then
echo "变量为空"
fi
4.2 命令取反 #
bash
#!/bin/bash
# 命令取反
if ! ping -c 1 google.com &>/dev/null; then
echo "网络不可用"
fi
# 检查命令不存在
if ! command -v git &>/dev/null; then
echo "git未安装"
fi
# 检查进程不存在
if ! pgrep nginx &>/dev/null; then
echo "nginx未运行"
fi
五、组合使用 #
5.1 && 和 || 组合 #
bash
#!/bin/bash
# 类似三元运算符
age=20
(( age >= 18 )) && echo "成年" || echo "未成年"
# 条件赋值
result=""
[[ -f config.sh ]] && result="存在" || result="不存在"
echo "配置文件$result"
# 注意:这种写法有陷阱
# 如果中间命令失败,会执行后面的命令
true && false || echo "这会执行"
# 更安全的写法
if [[ -f config.sh ]]; then
result="存在"
else
result="不存在"
fi
5.2 复杂逻辑组合 #
bash
#!/bin/bash
# 使用括号分组
age=25
has_license=true
if [[ ($age -ge 18 && $age -le 65) && $has_license == true ]]; then
echo "可以驾驶"
fi
# 多条件组合
score=75
attendance=90
if [[ ($score -ge 60 && $attendance -ge 80) || $score -ge 90 ]]; then
echo "通过考核"
fi
# 使用 ! 取反
if [[ ! ($score -lt 60 || $attendance -lt 80) ]]; then
echo "通过考核"
fi
5.3 命令组合 #
bash
#!/bin/bash
# 确保目录存在
mkdir -p /tmp/myapp || { echo "创建目录失败"; exit 1; }
# 多步骤操作
cd /tmp/myapp && {
touch config.ini
echo "初始化完成"
} || {
echo "操作失败"
exit 1
}
# 检查多个条件
command -v git >/dev/null && command -v make >/dev/null || {
echo "缺少必要工具"
exit 1
}
六、[ ] 中的逻辑运算 #
6.1 使用 -a 和 -o #
bash
#!/bin/bash
a=10
b=5
# -a 等同于 &&
if [ $a -gt 0 -a $b -gt 0 ]; then
echo "a和b都大于0"
fi
# -o 等同于 ||
if [ $a -gt 20 -o $b -gt 0 ]; then
echo "a大于20或b大于0"
fi
# 使用 !
if [ ! $a -eq 0 ]; then
echo "a不等于0"
fi
6.2 推荐使用 [[ ]] #
bash
#!/bin/bash
# 不推荐:使用 -a -o
if [ $a -gt 0 -a $b -gt 0 ]; then
echo "不推荐写法"
fi
# 推荐:使用 [[ ]] 和 && ||
if [[ $a -gt 0 && $b -gt 0 ]]; then
echo "推荐写法"
fi
# 或者使用单独的条件
if [ $a -gt 0 ] && [ $b -gt 0 ]; then
echo "另一种推荐写法"
fi
七、实战示例 #
7.1 参数验证 #
bash
#!/bin/bash
validate_args() {
# 检查参数数量
[[ $# -lt 2 ]] && { echo "用法: $0 <文件> <模式>"; exit 1; }
local file=$1
local pattern=$2
# 检查文件存在
[[ ! -f "$file" ]] && { echo "错误: 文件 $file 不存在"; exit 1; }
# 检查文件可读
[[ ! -r "$file" ]] && { echo "错误: 文件 $file 不可读"; exit 1; }
# 检查模式非空
[[ -z "$pattern" ]] && { echo "错误: 模式不能为空"; exit 1; }
echo "参数验证通过"
}
validate_args "$@"
7.2 服务检查脚本 #
bash
#!/bin/bash
check_service() {
local service=$1
# 检查服务是否存在
if ! systemctl list-unit-files "$service.service" &>/dev/null; then
echo "服务 $service 不存在"
return 1
fi
# 检查服务状态
if systemctl is-active --quiet "$service"; then
echo "服务 $service 正在运行"
return 0
else
echo "服务 $service 未运行"
return 1
fi
}
# 检查多个服务
services=("nginx" "mysql" "redis")
for svc in "${services[@]}"; do
check_service "$svc" || echo "请检查 $svc 服务"
done
7.3 条件安装脚本 #
bash
#!/bin/bash
install_package() {
local package=$1
# 检查是否已安装
if command -v "$package" &>/dev/null; then
echo "$package 已安装"
return 0
fi
# 检测包管理器并安装
if command -v apt-get &>/dev/null; then
sudo apt-get update && sudo apt-get install -y "$package"
elif command -v yum &>/dev/null; then
sudo yum install -y "$package"
elif command -v brew &>/dev/null; then
brew install "$package"
else
echo "未找到支持的包管理器"
return 1
fi
}
install_package "git"
install_package "vim"
7.4 数据验证脚本 #
bash
#!/bin/bash
validate_user_input() {
local username=$1
local email=$2
local age=$3
# 验证用户名
if [[ -z "$username" ]]; then
echo "错误:用户名不能为空"
return 1
fi
if (( ${#username} < 3 || ${#username} > 20 )); then
echo "错误:用户名长度应在3-20之间"
return 1
fi
# 验证邮箱
if [[ ! "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "错误:邮箱格式不正确"
return 1
fi
# 验证年龄
if ! [[ "$age" =~ ^[0-9]+$ ]]; then
echo "错误:年龄必须是数字"
return 1
fi
if (( age < 1 || age > 150 )); then
echo "错误:年龄应在1-150之间"
return 1
fi
echo "验证通过"
return 0
}
validate_user_input "张三" "test@example.com" 25
八、逻辑运算符速查 #
8.1 条件判断中 #
| 运算符 | 说明 | 示例 |
|---|---|---|
| && | 逻辑与 | [[ $a && $b ]] |
| || | 逻辑或 | [[ $a || $b ]] |
| ! | 逻辑非 | [[ ! $a ]] |
8.2 命令连接中 #
| 运算符 | 说明 | 示例 |
|---|---|---|
| && | 前面成功执行后面 | cmd1 && cmd2 |
| || | 前面失败执行后面 | cmd1 || cmd2 |
| ; | 顺序执行 | cmd1 ; cmd2 |
8.3 [ ] 中的运算符 #
| 运算符 | 说明 | 示例 |
|---|---|---|
| -a | 逻辑与 | [ $a -gt 0 -a $b -gt 0 ] |
| -o | 逻辑或 | [ $a -gt 0 -o $b -gt 0 ] |
| ! | 逻辑非 | [ ! $a -eq 0 ] |
九、总结 #
9.1 关键要点 #
&&表示逻辑与,两边都为真才为真||表示逻辑或,一边为真就为真!表示逻辑非,取反- 推荐使用
[[ ]]和&&|| - 注意短路求值的特性
9.2 下一步 #
你已经掌握了逻辑运算符,接下来让我们学习 字符串运算符,了解Shell中的字符串操作!
最后更新:2026-03-27