《Shell 大道:筑基篇(下)—— 流控筑根基,数据任驱驰》

文章目录

  • 前言
  • 一、逻辑运算符
    • [1.1 `&&`(逻辑与)](#1.1 &&(逻辑与))
    • [1.2 `||`(逻辑或)](#1.2 ||(逻辑或))
    • [1.3 组合使用:`A && B || C`](#1.3 组合使用:A && B || C)
  • [二、echo 命令与输出流](#二、echo 命令与输出流)
    • [2.1 输出到标准输出(`stdout`)](#2.1 输出到标准输出(stdout))
    • [2.2 输出到标准错误(`stderr`)](#2.2 输出到标准错误(stderr))
  • 三、标准文件描述符(`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 同时重定向 stdoutstderr)
      • [4.5.1 POSIX 推荐写法](#4.5.1 POSIX 推荐写法)
      • [4.5.2 Bash 简写](#4.5.2 Bash 简写)
  • 五、丢弃输出:`/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 同时重定向 stdoutstderr

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:

    bash 复制代码
     some_command > /dev/null
  • 丢弃 stderr:

    bash 复制代码
     some_command 2> /dev/null
  • 同时丢弃 stdout 和 stderr:

    bash 复制代码
     some_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"给FD1
    • echo err >&2:这边的作用是输出"err"给FD2
  • >both.txt :这一部分的命令同样进行了省略,实际为1>both.txt,意思是将FD1输出流的地址从命令行界面重定向为了一个文件both.txt
  • 2>&1:这的作用则是将FD2输出流的地址重定向到FD1输出流的地址,也因为这样>both.txt2>&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)可拓展数据通道,应对复杂场景。

此流控之术虽不似流程控制那般显化 "符阵框架",却是筑基期的 "内功核心"------ 若无流控,符阵灵气易乱、数据易失,后续构建复杂脚本、处理异常皆无从谈起。今汝筑基道基无瑕,既能搭符阵之架,又能控灵气之流,已具备向《金丹篇》迈进的资格。下一站,吾在金丹之境,静候道友前来!

相关推荐
杰克逊的日记1 小时前
gpu与cpu各厂商的优劣
运维·cpu·gpu
伞啊伞2 小时前
shell命令扩展
linux·运维
ajax_beijing3 小时前
ETL 在华为云上的最佳替代方案
大数据·linux·华为云
‍。。。6 小时前
ubuntu 安装 vllm
linux·运维·ubuntu
Ka1Yan6 小时前
什么是策略模式?策略模式能带来什么?——策略模式深度解析:从概念本质到Java实战的全维度指南
java·开发语言·数据结构·算法·面试·bash·策略模式
xiao-xiang6 小时前
zookeeper-集群扩缩容
linux·分布式·zookeeper·中间件·注册中心·zk
forestqq7 小时前
华为L420国产笔记本(统信UOS桌面专业版1070)安装openEuler2403虚拟机
运维·虚拟化·统信
zzz100667 小时前
Shell 编程基础(续):流程控制与实践
linux·运维·服务器
蒲公英的孩子7 小时前
Linux下OpenRadioss源码编译安装及使用
linux·分布式·开源软件
leon_teacher8 小时前
HarmonyOS权限管理应用
android·服务器·前端·javascript·华为·harmonyos