Shell 秘典(卷二)——号令延展秘术 与 流程掌控心法・if 天机判语篇精解
文章目录
- 前言
- 一、命令扩展详解
- 1.1 逻辑运算符
- 1.1.1 逻辑与运算符(&&)
- 1.1.2 逻辑或运算符(||)
- 1.1.3 组合使用注意事项
- 1.2 echo 命令
- 1.2.1 基本用法
- 1.2.2 输出到标准错误(stderr)
- 1.3 标准文件描述符(FD)
- 1.3.1 文件描述符说明
- 1.3.2 示例演示
- 1.4 重定向操作
- 1.4.1 覆盖重定向(>)
- 1.4.2 追加重定向(>>)
- 1.4.3 错误输出重定向(2> / 2>>)
- 1.5 同时重定向 stdout 与 stderr
- 1.5.1 POSIX 推荐写法
- 1.5.2 Bash 简写形式
- 1.6 丢弃输出:/dev/null
- 1.6.1 丢弃 stdout
- 1.6.2 丢弃 stderr
- 1.6.3 同时丢弃 stdout 和 stderr
- 1.7 管道(|)与重定向的区别
- 1.7.1 基本用法
- 1.7.2 包含 stderr 的管道
- 1.8 高级技巧:自定义文件描述符
- 1.8.1 打开与写入自定义 FD
- 1.9 小结与备忘
- 二、流程控制之if条件语句
- 2.1 流程控制概述
- 2.2 if 格式1:单支
- 2.3 if 格式2:双支
- 2.4 if 格式3:多支
- 总结
前言
Shell 秘典,乃 Linux/Unix 修仙界中执掌自动化运维、料理日常要务的无上法门。此秘典内蕴的号令组合之玄妙、流程掌控之神通,犹如修仙者手中的本命法宝,能大幅提升修士在系统界域内的管理修为,助其轻松应对各类繁杂事务。
本文决意深入拆解 Shell 秘典中的号令延展秘术 —— 诸如逻辑运化符、重定向术、管道通玄术等,更会详解流程掌控心法・if 天机判语篇。行文之间,将辅以海量修仙实例与真实界域应用场景,如同修仙大能亲授秘籍,引领诸位修士洞悉 Shell 秘典的核心符文与编程神通。
无论你是初入 Linux/Unix 修仙界、刚触摸修行门槛的萌新修士,还是渴望夯实基础、突破修为瓶颈的中级行者,这篇修仙指南都将为你奉上清晰明了、实用至极的修行指引,助你在 Shell 秘典的修行之路上畅通无阻,早日修成运维大道,成为一方系统界域的掌控者。
一、命令扩展详解
1.1 逻辑运算符
1.1.1 逻辑与运算符(&&)
含义:
仅当左侧命令执行成功(即退出状态码为 0)时,才执行右侧的命令。
示例:
false && echo "成功"
# 无输出,因为 `false` 失败(退出码非0),右侧命令不执行true && echo "成功"
成功
# true 成功(退出码为0),因此执行 echo 命令
1.1.2 逻辑或运算符(||)
含义:
仅当左侧命令执行失败(即退出状态码非 0)时,才执行右侧的命令。
示例:
false || echo "左侧失败,执行此处"
左侧失败,执行此处true || echo "不会执行"
# 无输出,因为 true 成功,右侧命令不执行
1.1.3 组合使用注意事项
说明:
A && B || C
从左到右结合,等价于 (A && B) || C
。
示例:
false && echo yes || echo fallback
fallback
# 因为 (false && echo yes) 不成立,于是执行 || 后面的 echo fallback
1.2 echo 命令
1.2.1 基本用法
含义:
将文本内容输出到标准输出(stdout,文件描述符为 1)。
示例:
echo "hello world"
hello world
1.2.2 输出到标准错误(stderr)
方法:
使用重定向 >&2
将文本发送到标准错误(stderr,文件描述符为 2)。
示例:
echo "this is error" >&2
# 文本将输出到 stderr
1.3 标准文件描述符(FD)
1.3.1 文件描述符说明
0
:stdin(标准输入)1
:stdout(标准输出)2
:stderr(标准错误)
1.3.2 示例演示
分别输出到 stdout 和 stderr:
echo "out"
out # 输出到 stdoutecho "err" >&2
err # 输出到 stderr
只重定向 stdout,stderr 仍显示在终端:
ls /no/such/path >out.txt
# 终端显示错误信息(stderr),out.txt 为空或不存在
1.4 重定向操作
- > 把 stdout 写到文件(覆盖原内容)
- >> 把 stdout 追加到文件末尾
1.4.1 覆盖重定向(>)
含义:
将 stdout 写入文件,若文件已存在则覆盖原有内容。
示例:
echo "first" > file.txt
echo "second" > file.txt
cat file.txt
second
1.4.2 追加重定向(>>)
含义:
将 stdout 追加到文件末尾,不覆盖原有内容。
示例:
echo "first" > file.txt
echo "second" >> file.txt
cat file.txt
first
second
1.4.3 错误输出重定向(2> / 2>>)
含义:
将 stderr(文件描述符 2)重定向到文件,支持覆盖或追加。
示例(覆盖):
ls /no/such/path 2>err.txt
cat err.txt
ls: cannot access '/no/such/path': No such file or directory
示例(追加):
ls /no/such/path 2>>err.txt
1.5 同时重定向 stdout 与 stderr
1.5.1 POSIX 推荐写法
格式:
command >out.txt 2>&1
含义:
先将 stdout 重定向到文件,再将 stderr 重定向到当前 stdout 指向的位置(即out.txt文件)。
示例:
bash -c 'echo out; echo err >&2' >both.txt 2>&1
cat both.txt
out
err
注意顺序:
以下写法会导致 stderr 仍输出到终端:
bash -c 'echo out; echo err >&2' 2>&1 >both.txt
这条会把 stderr 重定向到 最初的 stdout(终端),然后再把 stdout 重定向到文件,结果是:错误仍打印到终端,而文件里只有 stdout 内容。
1.5.2 Bash 简写形式
格式:
command &>file
或 command |& other
说明:
&>
:将 stdout 和 stderr 都写入文件(Bash 特性)|&
:将 stdout 和 stderr 都送入管道(Bash/Zsh 特性)
示例:
bash -c 'echo out; echo err >&2' &> both.txt
cat both.txt
out
err
1.6 丢弃输出:/dev/null
1.6.1 丢弃 stdout
含义:把不想要的输出重定向到 /dev/null (黑洞)。
示例:只保留 stderr,丢弃 stdout:
方法:
some_command > /dev/null
1.6.2 丢弃 stderr
方法:
some_command 2> /dev/null
1.6.3 同时丢弃 stdout 和 stderr
方法(POSIX):
some_command > /dev/null 2>&1
方法(Bash 简写):
some_command &> /dev/null
1.7 管道(|)与重定向的区别
含义:把前一个命令的 stdout 作为下一个命令的 stdin。默认只传输 stdout,不包含 stderr(除非你把stderr 重定向到 stdout)。
1.7.1 基本用法
含义:
将前一个命令的 stdout 作为下一个命令的 stdin。默认不包含 stderr。
示例:
echo -e "apple\nbanana" | grep banana
banana
1.7.2 包含 stderr 的管道
方法:
command 2>&1 | grep something
# 或使用 Bash 简写:
command |& grep something
示例:
# sed -n 'P' 等价于 cat
bash -c 'echo out; echo err >&2' 2>&1 | sed -n 'p'
out
err
1.8 高级技巧:自定义文件描述符
1.8.1 打开与写入自定义 FD
方法:
使用 exec
打开一个新的文件描述符,并写入内容。
示例:
exec 3>mylog.txt # 将文件描述符 3 重定向到文件mylog.txt
echo "hello" >&3 # 将 "hello" 写入到文件描述符 3 关联的文件(即 mylog.txt)
exec 3>&- # 释放文件描述符 3 的资源,确保文件被正确关闭
cat mylog.txt
hello
说明:
该技巧常用于脚本中管理多个日志流或输出通道。
1.9 小结与备忘
&&
:左侧成功才执行右侧||
:左侧失败才执行右侧>
:覆盖 stdout,>>
:追加 stdout2>
和2>>
:用于重定向 stderr- 将 stderr 重定向到 stdout:
2>&1
(注意顺序) - 同时重定向 stdout 和 stderr:
- POSIX:
>file 2>&1
- Bash:
&>file
- POSIX:
- 丢弃输出:
/dev/null
,可配合2>/dev/null
或&>/dev/null
- 管道
|
默认只传输 stdout;需传输两者时使用2>&1 |
或|&
(Bash)
二、流程控制之if条件语句
2.1 流程控制概述
任何程序都有默认的执行流程,通常是从上向下
逐行依次执行。
#!/bin/bash #先执行的第1行
num=100 #第2行
((num++)) #第3行
echo $num #第4行
.........
要控制程序的默认执行流程,可以使用流程控制语句:
- 选择结构:选择性执行特定代码段
- 循环结构:重复执行代码段,直到满足终止条件(通过条件控制循环次数)
Shell提供了多种判断方式,支持对数字、字符串和文件的操作。
2.2 if 格式1:单支
if [ 条件 ]; then
命令…
fi
执行机制:判断一次,仅有一个结果
- 条件成立(true):执行命令
- 条件失败(false):没有任何执行
示例:
#!/bin/bash
num1=$1 #第一个参数赋值给num1
num2=$2
if [ $num1 -gt $num2 ]; thenecho "$num1 大于 $num2"
fi## 执行shell程序
./ifdemo.sh 10 5
案例1:ls /mnt 如果执行成功,输出 it’s OK
#!/bin/bash
if ls /mnt # ls /mnt执行成功,输出 it's OK
thenecho " it's OK"
fi
2.3 if 格式2:双支
if [ 条件 ]; then
命令1…
else
命令2…
fi
执行机制:判断一次条件,有两个不同结果
- 条件成立(true):执行 then 后面的代码(命令1)
- 条件失败(false):执行 else 后面的代码(命令2)
示例:
#!/bin/bash
num1=$1 #第一个参数赋值给num1
num2=$2
if [ $num1 -qt $num2 ]; thenecho "$num1 大于 $num2"
elseecho "$num1 小于 $num2"
fi
分别执行./ifdemo.sh 10 5
和./ifdemo.sh 5 10
查看结果:
./ifdemo.sh 10 5
./ifdemo.sh 5 10
案例1:判断当前登录用户是不是管理员
#!/bin/bash
if [ $UID -eq 0 ]; thenecho "当前用户是管理员"
elseecho "当前用户是普通用户"
fi
案例2:判断目录是否存在
#!/bin/bash
read -p "检查目录是否存在, 请输入目录:" aa
if ls $aa > /dev/null
thenecho "目录存在"
elseecho "请输入正确路径"
fi
案例3:校验httpd服务是否启动
#!/bin/bash
if netstat -antulp| grep ":80" &> /dev/null; thenecho "web网站服务已经运行了!"
elseecho "启动httpd服务"if rpm -q httpd &> /dev/null; thenecho "httpd服务已安装,启动httpd服务"systemctl restart httpdelseecho "httpd服务未安装,开始下载httpd服务"yum install -y httpd > /dev/nullsystemctl restart httpdfiecho "httpd服务已启动!"
fi
案例4:校验ip是否可以ping通
#!/bin/bash
#ip=$1
read -p "请输入IP:" ip
#-c 次数 -i ping一次多少秒 -W 反馈结果的时间
ping -c 2 -i 0.2 -W 3 $ip &> /dev/nullif [ $? -eq 0 ];thenecho "$ip is up "
elseecho "$ip is down"
fi
2.4 if 格式3:多支
if [ 条件1 ]; then
命令1…
elif [ 条件2 ]; then
命令2
......elif
else
默认命令…
fi
执行机制:系统会依次检查多个判断条件,一旦某个条件成立,则执行对应的操作并终止后续判断;若所有条件均不满足,则执行默认操作。
例如,若第1个条件成立,则仅执行命令1,跳过其余条件判断。
示例:
#!/bin/bash
read -p "请输入您的分数" score
if [ $score -ge 90 ]; thenecho "优秀" # 分数>=90 优秀
elif [ $score -ge 80 ]; thenecho "良好" # 80<=分数<90 良好
elif [ $score -ge 60 ]; thenecho "及格"
elseecho "不及格"
fi# 执行脚本
./ifdemo.sh
案例1:判断用户输入数字是奇数还是偶数
#!/bin/bash
read -p "请输入一个整数" num
if [ $[num % 2] -eq 0 ]; thenecho "$num 是偶数"
elseecho "$num 是奇数"
fi
案例2:用户输入两个数,判断大小
#!/bin/bash
read -p "请输入第一个整数" num1
read -p "请输入第二个整数" num2
if [ $num1 -gt $num2 ];thenecho "$num1 > $num2"
elif [ $num1 -lt $num2 ];thenecho "$num1 < $num2"
elseecho "$num1 = $num2"
fi
案例3:判断文件类型 d f b
#!/bin/bash
read -p "输入一个文件名:" filename
if [ -z $filename ] || [ ! -e $filename ]; thenecho "文件不存在"
elif [ -f $filename ]; thenecho "$filename 是普通文件"
elif [ -d $filename ]; thenecho "$filename 是目录"
elif [ -b $filename ]; thenecho "$filename 是块设备文件"
elseecho "母鸡呀"
fi
总结
本文以修仙传承之法,系统拆解 Shell 秘典两大核心修行要诀:其一为号令延展秘术(命令扩展),可助修士灵活运化界域指令,如御万千法符组百变神通;其二是流程掌控心法・if 天机判语篇(流程控制之 if 条件语句),能勘破事务逻辑,依情境决断应对之策,乃执掌系统界域的根基。
二者相辅相成,构 Shell 修仙法门核心骨架。唯有融会贯通此两大要诀,方能在 Linux/Unix 界域修行中筑牢道基,为后续探寻高深运维通天术法铺路。
在号令延展秘术(命令扩展)部分,我们详细讲解了:
- 逻辑运算符
&&
和||
的使用场景与执行机制; echo
命令的输出控制与重定向技巧;- 标准文件描述符(stdin、stdout、stderr)的作用与重定向方法;
- 如何同时处理 stdout 和 stderr,以及如何丢弃不必要的输出;
- 管道与重定向的区别与联合使用;
- 高级技巧如自定义文件描述符的打开与关闭。
在流程掌控心法・if 天机判语篇部分,我们重点剖析了 if 条件语句的三种结构:
- 单支结构:条件成立时执行特定命令;
- 双支结构:根据条件成立与否分别执行不同命令;
- 多支结构:依次判断多个条件,执行第一个成立的条件对应的命令。
通过多场修仙实战历练 —— 诸如灵脉服务状态勘验(服务状态检查)、界域网络通玄测试(网络连通性测试)、宝器文件品类辨识(文件类型判断)等,吾等将展演 if 天机判语在系统界域执掌中的典型妙用,助力诸位修士洞悉其运转玄机,习得炼制稳固脚本秘宝的神通。
悟透这些基础符文奥义与编程玄功,非但能提升脚本秘宝的炼制效率,更可增强秘宝的稳固性与可修缮性,为后续修习更繁复的自动化通天术法筑牢根基,助你在 Linux/Unix 修仙界的修行之路更上一层楼,早日具备执掌复杂系统界域的大能。