文章目录
- 前言
- 一、逻辑运算符
-
- [1.1 `&&`(逻辑与)](#1.1
&&
(逻辑与)) - [1.2 `||`(逻辑或)](#1.2
||
(逻辑或)) - [1.3 组合使用:`A && B || C`](#1.3 组合使用:
A && B || C
)
- [1.1 `&&`(逻辑与)](#1.1
- [二、echo 命令与输出流](#二、echo 命令与输出流)
-
- [2.1 输出到标准输出(`stdout`)](#2.1 输出到标准输出(
stdout
)) - [2.2 输出到标准错误(`stderr`)](#2.2 输出到标准错误(
stderr
))
- [2.1 输出到标准输出(`stdout`)](#2.1 输出到标准输出(
- 三、标准文件描述符(`FD`)
- 四、重定向操作
-
- [4.1 `>` 与 `>>`:重定向输出`stdout`](#4.1
>
与>>
:重定向输出stdout
) - [4.2 `2>` 与 `2>>`:重定向错误输入 `stderr`](#4.2
2>
与2>>
:重定向错误输入stderr
) - [4.3 `<`:重定向输入](#4.3
<
:重定向输入) - [4.4 `<(...)`:进程替换](#4.4
<(...)
:进程替换) - [4.5 同时重定向 `stdout` 与 `stderr`](#4.5 同时重定向
stdout
与stderr
) -
- [4.5.1 POSIX 推荐写法](#4.5.1 POSIX 推荐写法)
- [4.5.2 Bash 简写](#4.5.2 Bash 简写)
- [4.1 `>` 与 `>>`:重定向输出`stdout`](#4.1
- 五、丢弃输出:`/dev/null`
- [六、管道` | `与错误流处理](#六、管道
|
与错误流处理) -
- [6.1 基本用法](#6.1 基本用法)
- [6.2 同时传输 `stdout `和 `stderr`](#6.2 同时传输
stdout
和stderr
)
- 七、进阶技巧:自定义文件描述符
-
- [7.1 从"一切皆文件"的特点理解重定向](#7.1 从“一切皆文件”的特点理解重定向)
- 总结
前言
【筑基进阶,流控入微】
道友已修成筑基初阶秘术,能以流程控制驭符阵、以函数化繁为简,然符阵运转的核心 ------"灵气(数据)流转",仍需进一步深造。练气期,汝仅能借read
收灵气、凭echo
散真气,对数据走向毫无掌控;而筑基进阶,需以 "逻辑运算符" 为开关,以 "重定向" 为改道符,以 "管道与文件描述符" 为传功索,让灵气按需流转、不溢不散。
本篇将授汝 "流控三术":其一为&&
与||
的 "开关妙法",依符阵(命令)成败定后续行止;其二为重定向(>
/>>
/2>
)的 "改道秘术",将灵气归入正途(stdout
)、岔路(stderr
)或黑洞(/dev/null
);其三为管道(|
)与文件描述符(0/1/2)的 "传功要诀",串联多符阵、多通道协同运转。此三术乃筑基进阶关键,练至大成,可让符阵灵气调度无滞,为后续应对 "异常劫雷(错误处理)" 筑牢根基。
一、逻辑运算符
1.1 &&
(逻辑与)
含义:仅当左侧命令成功(退出状态码为 0)时才执行右侧命令。
因此可以使用&&
当作一个特殊的if
循环,&&
左侧为if的判断条件,右侧为判断成功执行的命令。
示例:
bash
false && echo "成功"
# 无输出,因为 false 失败
true && echo "成功"
成功
# true 成功,执行 echo

1.2 ||
(逻辑或)
含义:仅当左侧命令失败(退出状态码非 0)时才执行右侧命令。
同&&
,||
也可以当做一个特殊的if
循环,&&
左侧为if的判断条件,右侧为判断失败后执行的命令。
示例:
bash
false || echo "左侧失败,执行此处"
# 左侧失败,执行此处
true || echo "不会执行"
# 无输出,因为 true 成功

1.3 组合使用:A && B || C
注意 :从左到右结合,等价于 (A && B) || C
。
示例:
bash
$ false && echo yes || echo fallback
fallback
# (false && echo yes) 失败,执行 fallback

二、echo 命令与输出流
2.1 输出到标准输出(stdout
)
用于程序输出正常的、预期的结果。
示例:
bash
echo "hello world"
hello world
2.2 输出到标准错误(stderr
)
专门用于输出错误信息或异常提示。
示例:
bash
echo "this is error" >&2
# 文本发送到 stderr
三、标准文件描述符(FD
)
在 Unix、Linux 及类 Unix 操作系统中,标准文件描述符(Standard File Descriptors) 是内核为每个进程预分配的、用于与外部设备 / 数据流交互的 "默认通道"。它们本质是整数标识,对应进程打开的文件(广义的 "文件",包括终端、管道、网络套接字等),让程序无需手动指定交互对象就能完成基础输入、输出和错误处理。
0
:stdin(标准输入)1
:stdout(标准输出)2
:stderr(标准错误)
示例:
bash
echo "out" # 输出到 stdout
echo "err" >&2 # 输出到 stderr
四、重定向操作
4.1 >
与 >>
:重定向输出stdout
改变命令的输出目的地,从默认的终端屏幕改为写入文件。
>
:覆盖写入文件>>
:追加写入文件
示例(覆盖):
bash
echo "first" > file.txt
echo "second" > file.txt
cat file.txt

示例(追加):
bash
echo "first" > file.txt
echo "second" >> file.txt
cat file.txt

4.2 2>
与 2>>
:重定向错误输入 stderr
将命令执行时产生的错误信息(如 "文件不存在")重定向到指定位置,而非默认显示在终端。
2>
:将错误信息覆盖写入文件2>>
:将错误信息追加写入文件
示例:
bash
ls /no/such/path 2>err.txt
cat err.txt

4.3 <
:重定向输入
改变命令的输入来源,从默认的键盘输入改为从文件读取。
示例:
bash
#! /bin/bash
# user_info.sh:读取姓名和年龄并输出
read -p "请输入你的姓名:" name # 读取输入赋值给 name 变量
read -p "请输入你的年龄:" age # 读取输入赋值给 age 变量
# 输出结果
echo -e "\n你的信息:"
echo "姓名:$name"
echo "年龄:$age"
bash
sh demo16.sh < test.sh #在不直接输入参数的情况下用test.sh中的内容进行输入


4.4 <(...)
:进程替换
在 Shell 中,<(...) 被称为进程替换(Process Substitution),它可以将一个命令的输出作为一个临时文件(或文件描述符)传递给另一个命令。
bash
# 将grep的输出作为wc -l的输入
wc -l < <(grep "error" file.txt)
grep "ERROR" <(cat /var/log/syslog)
#等价于 cat /var/log/syslog | grep "ERROR",但用进程替换的写法更直观。
4.5 同时重定向 stdout
与 stderr
4.5.1 POSIX 推荐写法
bash
command >out.txt 2>&1
示例:
bash
bash -c 'echo out; echo err >&2' >both.txt 2>&1
cat both.txt

注意顺序:以下写法错误,stderr 仍会输出到终端:
bash
bash -c 'echo out; echo err >&2' 2>&1 >both.txt

4.5.2 Bash 简写
在Bash中可以使用简写。
bash
command &>file # 同时重定向 stdout 和 stderr
command |& other # 同时管道传输 stdout 和 stderr
示例:
bash
bash -c 'echo out; echo err >&2' &> both.txt
cat both.txt

五、丢弃输出:/dev/null
含义 :将不需要的输出重定向到 /dev/null
(黑洞设备)。
示例:
-
丢弃 stdout:
bashsome_command > /dev/null
-
丢弃 stderr:
bashsome_command 2> /dev/null
-
同时丢弃 stdout 和 stderr:
bashsome_command > /dev/null 2>&1 # 或 some_command &> /dev/null
六、管道|
与错误流处理
6.1 基本用法
含义:将前一个命令的 stdout 作为下一个命令的 stdin。
管道|
,重定向输入>
,重定向输出<
的三者间的区别
- 管道
|
:从一个命令到另一个命令 - 重定向输入
>
:从一个命令到一个文件 - 重定向输出
<
:从一个文件到一个命令
示例:
bash
echo -e "apple\nbanana" | grep banana

6.2 同时传输 stdout
和 stderr
bash
command 2>&1 | grep something
# 或(Bash)
command &> | grep something
command |& grep something
示例:
bash
bash -c 'echo out; echo err >&2' 2>&1 | sed -n 'p'

七、进阶技巧:自定义文件描述符
用途:在脚本中管理多个输出流。
示例:
bash
exec 3>mylog.txt # 打开 FD 3 指向文件
echo "hello" >&3 # 写入 FD 3
exec 3>&- # 关闭 FD 3
cat mylog.txt

7.1 从"一切皆文件"的特点理解重定向
从上面的打开"FD3"输出流,以及"exec 3>mylog.txt"、"echo "hello" >&3"的写法不难得出"&1"、"&2"也是一个指向文件的输出流。而作为一个"一切皆文件"的系统,"&1"、"&2"指向的是命令行页面,因为当不使用重定向时,正确或错误的信息会直接输出在命令行的界面上,也就是说"命令行界面也被视为了一个文件 ",这也就能理解为什么>
、<
这些符号不直接叫输入、输出,而是叫重定向输入、重定向输出。
bash
bash -c 'echo out; echo err >&2' >both.txt 2>&1
bash -c 'echo out; echo err >&2' 2>&1 >both.txt

再用上方的例子理解一下重定向:
bash -c 'echo out; echo err >&2'
: 执行一个子bash,在其中执行了"echo out; echo err >&2"命令echo out
:实际是echo out >&1
,将>&1
进行了省略,作用是输出"out"给FD1echo err >&2
:这边的作用是输出"err"给FD2
>both.txt
:这一部分的命令同样进行了省略,实际为1>both.txt
,意思是将FD1输出流的地址从命令行界面重定向为了一个文件both.txt2>&1
:这的作用则是将FD2输出流的地址重定向到FD1输出流的地址,也因为这样>both.txt
、2>&1
的前后顺序,会对最后的结果产生影响,2>&1
在前时先进行了FD2输出流的地址重定向到FD1输出流的地址的过程,此时FD2的指向文件仍是命令行界面,再执行>both.txt
则是仅再次改变了FD1输出流的输出地址,最终结果就变成了再命令行界面输出"err",而在both.txt
输出了"out"。同理,可以看出2>&1
在后时的结果是'echo out; echo err >&2'
的命令都输出到了"both.txt"中
总结
【流控功成,筑基圆满】
贺喜道友!筑基进阶 "流控" 神通已成,至此筑基之境圆满!
此刻,汝已通晓逻辑运算符的 "开关之道":&&
仅在前方符阵成功时续接术法,||仅在前方符阵失败时补位,二者结合可精准控制符阵流程;熟稔重定向的 "改道之术":>
/>>
掌控标准输出,2>
/2>>
收纳错误信息,更能以&>
同时调度双流向,让数据按需归位;亦掌握管道与文件描述符的 "协同之法":管道串联多符阵,让灵气层层传递;自定义文件描述符(如 FD3)可拓展数据通道,应对复杂场景。
此流控之术虽不似流程控制那般显化 "符阵框架",却是筑基期的 "内功核心"------ 若无流控,符阵灵气易乱、数据易失,后续构建复杂脚本、处理异常皆无从谈起。今汝筑基道基无瑕,既能搭符阵之架,又能控灵气之流,已具备向《金丹篇》迈进的资格。下一站,吾在金丹之境,静候道友前来!