0%

详解重定向

详解重定向

前面已经多次用到重定向。

但是你以为重定向就那点东西吗?too young too simple。

前面已经接触到的重定向有:

1
2
3
4
5
6
>
>>
<
>| # 还记得这个吗。set -C,文件不能被重定向覆盖。用这个符号可以强行覆盖掉。
<<END # 是的,here文档也是一种重定向
<<<STRING # here String也是一种重定向

完整的再学习一遍

文件描述符

1
2
3
4
5
6
/dev/fd/fd						fd是一个正整数
/dev/stdin 标准输入,0
/dev/stdout 标准输出,1
/dev/stderr 标准错误输出,2
/dev/tcp/host/port tcp套接字
/dev/udp/host/port udp套接字

输入重定向

1
2
3
4
5
6
7
8
[n]<word			# n是一个文件描述符,如果n没有指定,则为0,标准输入

[root@vm-101 ~]# cat b
aaaa
[root@vm-101 ~]# cat < b
aaaa
[root@vm-101 ~]# cat 2< b
^C # 这里卡住了,因为文件b被重定向到2上了。而cat正在等待0中的内容。

输出重定向

[n]>word 这个看到很多了。跳过。

[n]>|word 回顾下。set -C

追加重定向

[n]>>word 这个也是。跳过。

重定向标准输出1和标准错误输出2

&>word and >&word

两个写法差不多。但是推荐第一种。

它等价于 >word 2>&1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@vm-101 ~]# cat a.sh
#! /bin/bash

echo "stdout"
cd adsdf

[root@vm-101 ~]# bash a.sh
stdout # stdout
a.sh: 第 4 行:cd: adsdf: 没有那个文件或目录 # stderr
[root@vm-101 ~]# bash a.sh > r.txt
a.sh: 第 4 行:cd: adsdf: 没有那个文件或目录 # stdout被重定向了,但是stderr没有被重定向
[root@vm-101 ~]# cat r.txt
stdout
[root@vm-101 ~]# bash a.sh &> r.txt # 两个都重定向了
[root@vm-101 ~]# cat r.txt
stdout
a.sh: 第 4 行:cd: adsdf: 没有那个文件或目录
[root@vm-101 ~]# echo > r.txt # 清空r.txt文件
[root@vm-101 ~]# cat r.txt

[root@vm-101 ~]# bash a.sh >& r.txt # 等同于bash a.sh &> r.txt写法
[root@vm-101 ~]# cat r.txt
stdout
a.sh: 第 4 行:cd: adsdf: 没有那个文件或目录
[root@vm-101 ~]# echo > r.txt
[root@vm-101 ~]# bash a.sh > r.txt 2>&1 # 效果一样
[root@vm-101 ~]# cat r.txt
stdout
a.sh: 第 4 行:cd: adsdf: 没有那个文件或目录

追加重定向标准输出1和标准错误输出2

1
2
&>>word
>>word 2>&1

与上面类似,只是上面是覆盖。这里是追加

Here文档

复习下语法

1
2
3
<<[-]word
here-document
delimiter

Here字符串

也复习下语法:

1
<<<word

复制文件描述符

[n]<&word [n]>&word

这里的word是文件句柄,是数字。不是文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@vm-101 ~]# echo > r.txt
[root@vm-101 ~]# ( echo aaaaa; cd asdfad ) > r.txt 2>&1
[root@vm-101 ~]# cat r.txt
aaaaa
bash: cd: asdfad: 没有那个文件或目录
[root@vm-101 ~]# echo > r.txt
[root@vm-101 ~]# ( echo aaaaa; cd asdfad ) > r.txt
bash: cd: asdfad: 没有那个文件或目录
[root@vm-101 ~]# cat r.txt
aaaaa
[root@vm-101 ~]# echo > r.txt
[root@vm-101 ~]# ( echo aaaaa; cd asdfad ) > r.txt 2<&1 # 效果一样
[root@vm-101 ~]# cat r.txt
aaaaa
bash: cd: asdfad: 没有那个文件或目录

2>&- 关闭2,关闭标准错误输出

如果n不指定,[n]<&word默认为 0<&word;[n]>&word默认为1<&word

移动文件句柄

[n]<&digit- and [n]>&digit-

和上面类似。区别在:复制完文件句柄后,digit要关闭。

打开文件句柄

[n]<>word

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@vm-101 ~]# exec 9<>9.txt				# 绑定文件描述符
[root@vm-101 ~]# cat 111 >&9
[root@vm-101 ~]# cat 9.txt
aaaa
[root@vm-101 ~]# echo asdfasdfasdfasdf >&9
[root@vm-101 ~]# cat 9.txt
aaaa
asdfasdfasdfasdf
[root@vm-101 ~]# echo asdfasdfasdfasdf3333333333 >&9
[root@vm-101 ~]# cat 9.txt
aaaa
asdfasdfasdfasdf
asdfasdfasdfasdf3333333333

[root@vm-101 ~]# exec 9>&- # 删除文件描述符
[root@vm-101 ~]# echo asdfasdfasdfasdf3333333333 >&9
bash: 9: 错误的文件描述符