Linux - Shell - Linux 标准 I/O 与 输出重定向
-
概述
- linux 输入输出流
- 入门
-
背景
- 尝试理解 linux 的 输入输出流
- 困扰了我很久, 但是一直没有做 总结
- 今天把这个坑填上
-
类型
- 教程向
-
环境
- OS
- centos7
- OS
1. shell 输入输出流
-
概述
- shell 输入输出流
-
场景: 日常使用 shell
-
概述
- 日常 shell
-
场景
- 日常使用 shell
-
使用模式
- 输入命令
- 输出结果
-
输入
- 通常是 键盘输入
-
输出
- 通常是 直接输出在 终端上
-
- 日常使用 shell
-
2. 文件描述符
-
概述
- shell 输入输出的原理
- 简单说一说, 方便理解
-
机制
- 进程 与 数据交互
-
进程的启动, 几乎都是为了做一些处理
- 基于 输入
- 给出 输出
-
但是 数据从哪里来, 到哪里去, 这个问题必须先想清楚
- 如何管理
- 如何描述
-
- 进程 与 数据交互
-
进程的处理: 文件描述符
-
位置
- 每个 进程 中
- 文件描述符表
-
文件
- linux 可以把很多东西, 都视为文件
- 数据流, 设备, 文件
- 这样会方便管理, 方便实现驱动
- linux 可以把很多东西, 都视为文件
-
机制
- 创建时机
- 进程 create, open 系统调用的时候
- 关联
- 描述符关联 文件 的 inode
- inode 再关联具体的文件
- 其他 - 后话
- 文件描述符, 是 进程 内的
- 同一个文件, 可能会被多个进程引用
- 它对应的文件描述符, 可能一样也可能不一样
- 只要能获取 文件描述符, 配置好 读写权限, 就可以配置各种不同类型的 io
- 创建时机
-
默认
-
默认
- 为了方便使用, linux 会给新进程, 配置 3 个流
- 作为 输入输出的载体
-
流
- 输入
- stdin - 默认对应键盘输入
- 编号为 0
- stdin - 默认对应键盘输入
- 输出
- stdout - 默认对应 终端
- 编号为 1
- stderr - 默认对应 终端
- 编号为 2
- stdout - 默认对应 终端
- 输入
-
-
问题
- 问题
- 说了那么多, 方便输入输出, 万一默认的不好使, 怎么办呢?
- 解答
- 办法当然有啦
- 问题
-
3. 重定向
-
概述
- 简单描述 重定向
-
准备
-
cat
- 查看文件的命令
- 会将 输入 直接打在 输出 上
-
查看文件描述符
-
命令
# pid 怎么来我就不说了 > ll /proc/<pid>/fd
-
-
1. 输入重定向
-
概述
- 输入重定向
-
输入
-
终端的输入
- 键盘
- 终端里的命令, 通常是 键盘 打进去的
- 粘贴的机制, 我暂时不清楚...
- 终端里的命令, 通常是 键盘 打进去的
- 键盘
-
命令的输入
-
参数
- 将 文件/设备/流 作为 参数, 传递给 命令
- 会 额外增加 新的文件描述符
- | xargs
-
输入流
- 直接使用 stdin
- 不会增加新的文件描述符
- |
-
-
-
例子
# 1. 使用 参数, 这个最常见 > cat <inputFile> # 2. 使用 stdin ## 输入 cat 命令后, 直接敲 回车 ## 然后的模式是, 输入一行, 回车一行, 显式一行 ## ctrl + c 退出 > cat # 3. 使用 stdin, 输入多行 ## EOF 是结束符, 可以换成别的 ## 输入多行后, 回车, 直接输出多行 > cat << EOF # 4. 输入重定向 ## 使用起来和 1 差不多 ## 区别是 不会额外使用 新的文件描述符 > cat < <inputFile>
2. 输出重定向
-
概述
- 输出重定向
-
输出
- 分类
- 标注输出 - stdout
- 标准异常 - stderr
- 分类
-
例子
# 1. 重定向 stdout ## 普通 ## 没有文件就创建, 有就直接覆盖 > cat <inputFile> > <stdoutFile> > cat <inputFile> 1> <stdoutFile> > cat <inputFile> &> <stdoutFile> ## 追加 ## 没有文件就创建, 有就继续追加 > cat <inputFile> >> <stdoutFile> > cat <inputFile> 1>> <stdoutFile> > cat <inputFile> &>> <stdoutFile> # 2. 重定向 stderr ## 普通 > cat <notExistFile> 2> <stderrFile> ## 追加 > cat <notExistFile> 2>> <stderrFile> # 3. 重定向 stdout 和 stderr ## 普通 > cat <inputFile> 1> <stdoutFile> 2> <stderrFile> ## 追加 > cat <inputFile> 1>> <stdoutFile> 2>> <stderrFile> ## 当然, 也可以昏庸 > cat <inputFile> 1> <stdoutFile> 2>> <stderrFile> # 4. 重定向 stdout 和 stderr 到同一文件 ## &1 表示 stdout 当前的目标 ## &2 类似 > cat <inputFile> 1> <logFile> 2>&1 ## 这样也可以, 但是上面的形式, 见的多一些 > cat <inputFile> 2> <logFile> 1>&2 ## 追加模式也可以 ## 追加模式, 只用 1 追加, 2 那个不用追加 > cat <inputFile> 1>> <logFile> 2>&1
3. 混合
-
概述
- 当然你要都混着, 也不是不可以
-
例子
> cat 1><log> 2>&1 > cat < anaconda-ks.cfg 1>> log 2>&1
4. 后续
-
文件描述符
- 概念
- 限制
-
后台执行
- &
- nohup
-
疑问: 子 shell 与 文件描述符
- 据说 子shell 会继承 父shell 的文件描述符
- 简单尝试了一下, 初步结论确实是这样
- 问题
- 单独重定向 stderr, 会导致 命令行 可以输入, 但无法刷新
- 单独重定向 stdout, 命令行 可以输入, 可以刷新, 但是没有结果
- 先重定向 stdout, 再重定向 stderr, 同情况1
- 据说 子shell 会继承 父shell 的文件描述符
ps
-
ref
-
- 概述
- 文件描述符
- 前置知识
- 概述
-
linux下两个进程可以同时打开同一个文件吗?返回的文件描述符一样吗?
-
概述
- 一个我对于 文件描述符 的疑问
-
结论
- 两个进程中分别产生生成两个独立的 fd
- 两个进程可以任意对文件进行读写操作,操作系统并不保证写的原子性
- 进程可以通过系统调用对文件加锁,从而实现对文件内容的保护
- 任何一个进程删除该文件时,另外一个进程不会立即出现读写失败
- 两个进程可以分别读取文件的不同部分而不会相互影响
- 一个进程对文件长度和内容的修改另外一个进程可以立即感知
-
-
What is the use of file descriptor 255 in bash process
- 一个问题
4 What was the point of separating stdout and stderr?
1. 为何要让 stderr 和 stdout 分开 1. 设计者 1. 早期计算机科学家 2. 原因 1. 早期日志查找, 完全靠人 2. 找异常相当痛苦 3. 于是决定, 将 stderr 分离出来 2. 这里 markdown 解析出了点问题, 格式我是真的调整不好了...
-
尽量尝试解释清楚; 自己校对能力有限, 如果有错误欢迎指出