流类型
类型 | 编号 | 说明 |
---|---|---|
stdin |
0 |
标准输入 |
stdout |
1 |
标准输出 |
stderr |
2 |
标准错误 |
重定向
符号 | 作用 | 效果 |
---|---|---|
> |
输出重定向 | 覆盖 |
>> |
输出重定向 | 追加 |
< |
输入重定向 | 输入 |
输出重定向
- 限定
# 基本数据填充 echo "old content" > /tmp/out.log # 重定向输出 echo "output redirect test" > /tmp/out.log # 追加重定向 echo "append content" >> /tmp/out.log
>
会直接覆盖文件内容,>>
会进行追加。
>
对于文件影响较大,不建议使用,同时可以添加额外限定。set -C
set -C
会取消>
的覆盖功能,当文件不存在的时候没有任何问题。如果文件存在的话就会报错。
如果需要可覆盖的话可以
set +C
。
- 类型
# 显示结果并重定向到指定文件 ls /var > /tmp/out.txt # ..... ls /varr > /tmp/out.txt
第一条指令会正常执行,而第二条指令会进行报错。
这是因为
/varr
这个文件夹不存在。具体的原因是
>
重定向默认操作的是stdout
,当报错的时候,操作对象换成了stderr
。类型不匹配,于是错误信息直接输出到控制台,没有直接输出到文件。
想要保存错误信息的话
ls /varr 2> /tmp/out.txt
通过
2
指定操作流为stdout
,即重定向错误输出
。这样就会把错误信息给重定向输出到指定文件。但是,此时
/varr
替换成/var
,信息就会直接显示,因为没有错误
。ls /var > /tmp/out.txt 2> /tmp/err.txt
采取
双重重定向
,相当于对每个流
进行了指定,存在的话就进行操作。还能够对不同的信息进行归类。
- 二合一
ls /var > /tmp/log.txt 2> /tmp/log.txt
两者指向同一个文件即可,不过还可以更方便一些。
ls /varr &> /tmp/log.txt
&
就能够自动整合两个流重定向到同一个文件。但是,只能
&>
,却没有&>>
。
输入重定向
- 简单输入流
cat < /etc/passwd
重定向输入流
cat /etc/passwd
:读取文件并输出
cat < /etc/passwd
:读取流并输出
- 文档输入流
echo << EOF > first > second > third > EOF
上面的
>
不在命令范围内,enter
就会自动换行并显示。当我们需要格式换行的时候,通过
<<
就可以进行多行的直接输入,而不是\n
。类似于
python
的三引号,能够自动识别格式。
EOF
是约定的结束标记,在命令最初必须指定结束标记,当输入该标记时,视作输入完毕。结束标记常用
END
或EOF
进行表示。
双向
- 直接输入到文本
cat >> godme.txt << EOF > first > second > third > EOF
屏幕输入,但是没有输出。
查看文本,全部进去了
管道
把前一个的输出连接作为后一个的输入,是谓管道。
- 只显示文件夹
ls -lhi | grep "^d"
- 文件名全大写
ll | tr 'a-z' 'A-Z'
双端
- 流方向
cat >> file << EOF
- 管道流向
- 流控制
重定向
并非是流控制
的手段。它只是改变了
流向
,更主要的是它的核心是操作
,所谓流不过是两端
的被隔绝的产物。我们总是通过
命令
才能把所谓的输入
同输出
关联起来。
cat >> godme.file << EOF
每次,都必须得有这么一个关联命令,不做额外操作的时候,仅仅
cat
,实在不便。
ls -lhi | grep "^-" | tr 'a-z' 'A-z'
如果说
重定向
通过命令连接了流
。那
管道
就是通过流
关联了命令。更多的场景下,我们更加关注的是命令的连接而不是流的连接。
管道
自动连接了流
,让操作更加方便。
- 差异
实体 | 作用 | 范围 |
---|---|---|
流 | I/O |
终端 |
管道 | O2I |
过程 |
- 差异
所谓流,描述的只是
程序(命令)
的元素
和结果
,通过程序
才有了一丝关联。所谓
管道
,也不具有实际含义,只是把结果
转接作为了元素
。流只关心
来源
和去处
,因此,它注定只能在两端具有用途。
管道
不关心来源
,也不关心去处
,它的核心作用是连接
,所以更多的使用在过程
当中。
- 同源
流
只是抽象的东西,更多的差异来源于操作,根源部分任然是同样的。
重定向
,让我们看到的是直接的流操作,注重流
的方向性和独立性。
管道连接
,屏蔽了重定向
和流对接
,更偏向于流的顺序性和相关性。不可把
操作
的差异理解为流
,这样会误入歧途。同时,区分、理解操作引起的差异,能够对流进行深入的理解。
- 渐进
- 重定向
重定向,让我们初步认识了流,并了解了基本概念。
- 管道
管道更深入一层,实现了
流管理
,让零散的独立的IO
连贯为O2I
。把
程序
弱化,把流程
曝光,把目光转移到更实用的地方。
tee
不过管道有一个小局限----单向输出。
管道实现了
对接
,不过还是留下了单向
的毛病。不过
tee
弥补了这个不足。# 重定向 cat >> godme.file << EOF # 管道tee cat << EOF | tee godme.txt
其中最关键的在于两点
- 流向
重定向
:input
-->cat
-->godme.file
,命令关联流。
管道tee
:input
-->cat
-->tee
-->godme.file
,cat --> tee
,流关联命令。
- 多方向
这个差别需要看现实结果
重定向
文本有结果,但是控制台无输出。
tee
两者都会有结果。这算是最明显的关系了。
管道实现了关联,单却只能单连接,
tee
可以关联到多个输入。
- tee
tee
实现的更多是分流
。首先,是多条流。
cat << EOF | tee godme.txt judas.txt foreva.txt
它能够直接连接多个文件进行输出。
然后必须理解的更关键的是
截取复制
ls -lhi | tee files.txt | wc -l
它的确能够输出到多个,但是,实际上它只是额外复制流指向指定的文件。
原本的流,依旧是存在的,没有截断,没有重定向,仅仅是重定向了复制的流,有多个流向时依然。
所谓的
分流
是在复制
之后,小细节。
小结
所谓的
程序到程序
,依然是建立在输出到输入
的关联之上。前面为了理解有所省略,但是一定要区分开来。