惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Security Blog
Microsoft Security Blog
量子位
大猫的无限游戏
大猫的无限游戏
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - Franky
美团技术团队
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理
罗磊的独立博客
Jina AI
Jina AI
小众软件
小众软件
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
雷峰网
雷峰网
博客园 - 聂微东
博客园_首页
The Cloudflare Blog
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队

お前はどこまで見えている

基于成交量预测市场走势 PowerShell常见问题 低延迟趋势线择时策略 波动率与换手率中的牛熊密码 通道突破择时策略 均线择时策略 Partial Plots 因子投资基础 Permutation Importance Use Cases for Model Insights 天文相关资源汇总 被讨厌的勇气 量化笔试数理知识复习 你当像鸟飞往你的山 Python模块logging 失去的二十年:日本经济长期停滞的真正原因 PyTorch的hook机制 A股交易规则 强化学习概述
深入理解BashShell重定向
hotarugali · 2024-05-28 · via お前はどこまで見えている

简介

Linux 终端下的重定向功能在日常办公中经常被使用到,深入理解并熟练掌握 Bash Shell 的重定向将有助于提升办公效率。Bash Shell 下的重定向是通过文件描述符实现的,Linux 系统默认有三个标准的文件描述符:

  • stdin:标准输入,文件描述符 0
  • stdout:标准输出,文件描述符 1
  • stderr:标准错误,文件描述符 2

假设 Linux 终端设备为 /dev/tty0,则 Linux 系统下标准文件描述符在 Bash Shell 中与设备的映射关系如下:

一种简单好理解重定向符的方法:将 >/< 看做是赋值语句中的 =,前者的方向代表后者的赋值方向;将 & 看做是 $

重定向标准输出到文件

1
command >file

其中,> 操作符是输出重定向操作符。Bash 首先会尝试打开 file 文件,如果成功打开则将 command 的标准输出发送到 file 文件中,并将原来的内容覆盖;如果无法打开,则该条命令执行失败并报错。

command >file 等价于 command 1>file,这是因为 1 是输出重定向默认的文件描述符。该命令下,文件描述表与设备的映射关系如下:

重定向到文件的一般命令为 command n>file,其中 n 为需要重定向的文件描述符。

为了避免不小心覆盖已有文件,可以为当前 Shell 设置 noclobber 选项:

1
set -o noclobber

这样之后,如果 file 已经存在,>file 就是报错。在这种情况下,如果你确定一定要覆盖,可以使用 >| 操作符。

1
command >| file

重定向标准错误到文件

1
command 2>file

该命令下,文件描述符表与设备的映射关系如下:

定向标准输出和标准错误到文件

1
command &>file

其中,&> 操作符用来同时重定向 stdoutstderr。该命令下,文件描述符表与设备的映射关系如下:

重定向的先后顺序

一种等价于 &> 操作的重定向命令为:

1
command >file 2>&1

其中,先后出现了两次重定向:

  • 第一次是将 stdout 重定向到 file
  • 第二次是将 stderr 重定向到文件描述符 1,而 1 已经被重定向到 file,所以等价于 stderr 重定向到 file

该命令下,文件描述符表与设备的映射关系如下:

与之不同的是,如果将 2>&1 提前到 >file,则对应的含义完全不同:

1
command 2>&1 >file

其中,先后出现了两次重定向:

  • 第一次是将 stderr 重定向到 stdout,此时 stdout 映射到终端 /dev/tty0,故等价于 stderr 重定向到 /dev/tty0
  • 第二次是将 stdout 重定向到 file

该命令下,文件描述符表与设备的映射关系如下:

丢弃标准输出

1
command > /dev/null

/dev/null 是 Linux 系统中特殊的虚拟设备,其会将发送给它的所有内容丢弃。

重定向标准输入

1
command <file

其中,< 操作符是输入重定向操作符。Bash 首先会尝试打开 file 文件,如果成功打开则 file 中的内容重定向到 command 作为输入;如果无法打开,则该条命令执行失败并报错。

该命令下,文件描述符表与设备的映射关系如下:

重定向多条文本到标准输入

1
2
3
4
5
6
7
command <<EOF
your
multi-line
text
goes
here
EOF

其中,<<MARKER 操作符用来重定向文本内容。该命令会将两个 MARKER 中包裹的文件内容重定向到标准输入。

重定向单行文件到标准输入

1
command <<< "foo bar baz"

该命令等价于:

1
echo "foo bar baz" | command

固定重定向标准错误到文件

1
2
3
4
exec 2>file
command1
command2
...

exec 是 Linux Bash 内建命令,该命令会将 stderr 固定重定向到 file 文件,直到再次修改重定向或退出当前的 Bash Shell。

固定输入重定向文件描述符

1
exec 3<file

该命令会尝试打开 file 文件,并分配文件描述符 3 指定到 file,用于后续输入需要。比如:

1
grep "foo" <&3

如果想要关掉文件描述符 3,则可以使用以用命令:

1
exec 3>&-

固定输出重定向文件描述符

1
2
exec 4>file
echo "foo" >&4

与输入重定向文件描述符一样,如果想要关掉文件描述符 4,可以使用以下命令:

1
exec 4>&-

固定输入输出重定向文件描述符

1
exec 3<>file

合并多输出重定向到文件

1
(command1; command2) >file

重定向到文件和终端

1
command | tee file

tee 命令常用来将输出重定向到文件,同时又保留终端输出。其工作方式如下:

管道通信

Bash Shell 下的管道 | 可以用来在不同命令间通信,比如:

1
command1 | command2

该命令会将 command1 的标准输出和 command2 的标准输入连接,其对应的输入输出映射关系如下:

如果需要将 command1 的标准错误也发送给 command2,可以使用 |& 操作符:

1
command1 |& command2

或者先将 command1 的标准错误重定向到其标准输出,即等价于以下命令:

1
command1 2>&1 | command2

交换标准输出和标准错误

1
command 3>&1 1>&2 2>&3

分别重定向标准输出和标准错误

1
command > >(stdout_cmd) 2> >(stderr_cmd)

其中,>(...) 操作符会将 ...stdin 连接到一个匿名管道,这里即对应 commandstdout,再执行 ...

重定向备忘卡

参考文献