程序锅

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于

  • 搜索
基础知识 Etcd LeetCode 计算机体系结构 Kubernetes Containerd Docker 容器 云原生 Serverless 项目开发维护 ELF 深入理解程序 Tmux Vim Linux Kernel Linux numpy matplotlib 机器学习 MQTT 网络基础 Thrift RPC OS 操作系统 Clang 研途 数据结构和算法 Java 编程语言 Golang Python 个人网站搭建 Nginx 计算机通用技术 Git

Linux Cheat Sheet - Bash 的数据流重导向

发表于 2021-01-03 | 分类于 Linux | 0 | 阅读次数 2689

数据流重导向

一般来说,执行一个命令时的流程如下所示:它会先从文件中读入数据,经过处理之后再将数据输出到屏幕上。

其中,standard input 表示的是标准输入,默认时从键盘中输入;standard output(stdout) 表示的是标准输出,是指指令执行所回传的正确信息;standard error output (stderr)表示的是标准错误输出,是指指令执行失败后,所回传的错误信息。比如,当我们使用 cat 指令查询 /etc/crontab 这个文件时,假如这个文件存在的话,那么此时文件内容会显示到屏幕上,而这个就是标准输出;当这个文件不存在的话,那么屏幕上就是显示错误信息,而这个就是标准错误输出。

那么,数据流重导向就是指将命令在终端的标准输出、标准出错重定向到别的地方比如文件中,或者读取文件的内容来取代标准输入。改变数据流重导向所用的特殊符号如下所示:

  1. 标准输入 (stdin) :代码为 0 ,使用 < 或 <<(结束输入的意思)
  2. 标准输出 (stdout):代码为 1 ,使用 >(以覆盖的方式将数据输出到指定的文件或设备上) 或 >>(以累加的方式将数据输出到指定的文件或设备上)
  3. 标准错误输出(stderr):代码为 2 ,使用 2> (同上,2 和 > 之间没有空格)或 2>>(同上)

下面先看下 stdout 和 stderr 的重导向:

# 将 ls -lh 的标准输出存到 stdout 这个文件中。如果原本没有这个文件,则创建这个文件;如果原本有这个文件,则将这个文件的内容全部替换。
ls -lh > stdout
ls -lh 1> stdout	# 此时需要注意 1 和 > 需要紧贴在一起

# 将 ls -lh 的标准输出追加到 stdout 这个文件中。如果原本没有这个文件,则创建这个文件;如果原本有这个文件,则将输出的内容追到这个文件原有内容的末尾。
ls -lh >> stdout
ls -lh 1>> stdout

# 将 ls -lh 的标准错误存到 stderr 这个文件中。
ls -lh 2> stderr

# 将 ls -lh 的标准输出存到 stdout 中,标准错误输出存到 stderr 中。
ls -lh > stdout 2> stderr	# 如果仅存在 > 时,则代表默认的代码 1
ls -lh 1> stdout 2> stderr

# 将 ls -lh 的标准输出存到 stdout 中,标准错误存到 /dev/null。/dev/null 可以吃掉任何导向这个设备的信息。
ls -lh 1> stdout 2> /dev/null

# 将 ls -lh 的标准输出和错误都输入到 stdouterr 这个文件中。
ls -lh 1> stdouterr 2>&1	# 推荐使用这种
ls -lh &> stdouterr	
# ls -lh 1> stdouterr 2> stdouterr,这种方式无法实现上述的效果。因为都是直接覆盖的,虽然可以使用追加的方式,但是这两种数据会交叉写入到该文件中。

再看下 stdin 的重导向,stdin 的重导向就是将原本从键盘输入的数据,改由文件内容来取代。

# 这里使用了两个重导向,一种是标准输出的重导向:cat > catfile 表示标准输出存到 catfile 这个文件中。之后加了一个 < .bashrc 表示将 .bashrc 这个文件的内容作为标准输入输进去。最终实现的是将 .bashrc 这个文件的内容传到 catfile 这个文件中。
cat > catfile < .bashrc

# << 代表的是“结束的输入字符”,比如下面这条命令则表示将键盘输入的信息输出到 catfile 文件中,且当键盘输入 eof 时结束该次输入。也就是说可以利用 << 来终止一次输入,而不必使用 ctrl+d 的方式来结束输入。
$ cat > catfile << "eof"
heredoc> demo
heredoc> demo
heredoc> demo
heredoc> eof	# 输入 eof 关键字之后就会停止输入了

命令执行的判断依据

# 1. 用分号连接。命令之间没有关联,分号前的指令执行完后就会立即接着执行后面的指令。
cmd1; cmd2; cmd3 

# 2. 用 && 连接。若 cmd1 执行完毕且正确执行($?=0),则开始执行 cmd2。若 cmd1 执行完毕且为错误 ($?≠0),则 cmd2 不执行。
cmd1 && cmd2

# 3. 用 || 连接。若 cmd1 执行完毕且正确执行($?=0),则 cmd2 不执行。若 cmd1 执行完毕且为错误 ($?≠0),则开始执行 cmd。
cmd1 || cmd2

# ls 查阅目录 /tmp/abc 是否存在,如果存在那么 $? 为 0,那么则使用 touch 创建 /tmp/abc/hehe
ls /tmp/abc && touch /tmp/abc/hehe

# 假如 /tmp/abc 不存在那么该指令执行回传 $?!=0,那么此时会执行 mkdir 这条指令。由于 mkdir 这条指令会执行成功,所以 touch 也会被执行。
# 假如 /tmp/abc 存在,那么该指令执行回传 $?=0,此时不会执行 mkdir 这条指令。此时 $?=0 这个结果会继续向后传,此时 touch 也会被执行。
ls /tmp/abc || mkdir /tmp/abc && touch /tmp/abc/hehe

# ls 测试 /tmp/abc 存不存在,如果存在的话那么则显示 exist,假如不存在的话,那么则显示 not exist。
# 一般来说,假如想要使用 && 和 || 实现判断,那么这两个的顺序是不能颠倒的。一般来说,顺序应该是:command1 && command2 || command3。
ls /tmp/abc && echo "exist" || echo "not exist"
# ls /tmp/abc || echo "not exist" && echo "exist" 这种顺序则是错误的,因为假设 /tmp/abc 不存在,那么会回传 $?!=0 那么第一个 echo 将会执行,并且肯定是执行成功的,此时 $?=0,因此第二个 echo 仍然会执行。这就违背了当初想要的效果了。
卷死我
dawnguo 微信支付

微信支付

dawnguo 支付宝

支付宝

  • 本文作者: dawnguo
  • 本文链接: /archives/98
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# Linux
Linux Cheat Sheet - Bash 概念、配置、操作环境和常用命令
Linux Cheat Sheet - 管道概念及常用管道命令
  • 文章目录
  • 站点概览
dawnguo

dawnguo

215 日志
24 分类
37 标签
RSS
Creative Commons
© 2018 — 2025 程序锅
0%