# Shell 标准输入输出

## 文件描述符

在Linux Shell执行命令时，每个进程都和三个打开的文件相联系，并使用文件描述符来引用这些文件。由于文件描述符不容易记忆Shell同时也给出了相应的文件名：

| 文件                   | 文件描述符                                   |
| ---------------------- | -------------------------------------------- |
| 输入文件--标准输入     | 0（缺省是键盘，为0时是文件或其他命令的输出） |
| 输出文件--标准输出     | 1（缺省是屏幕，为1时是文件）                 |
| 错误输出文件--标准错误 | 2（缺省是屏幕，为2时是文件）                 |

## 文件重定向

改变成程序运行的输入来源和输出地点。

### 输出重定向

| 命令             | 描述                                           |
| ---------------- | ---------------------------------------------- |
| cmd > file       | 把标准输出重定向到一个文件中                   |
| cmd >> file      | 把标准输出重定向到一个文件中（追加）           |
| cmd > file 2>&1  | 把标准输出和错误一起重定向到一个文件中         |
| cmd 2 > file     | 把标准错误重定向到一个文件中                   |
| cmd 2>> file     | 把标准错误重定向到一个文件中（追加）           |
| cmd >> file 2>&1 | 把标准输出和错误一起重定向到一个文件中（追加） |

### 输入重定向

| 命令                | 描述                                                    |
| ------------------- | ------------------------------------------------------- |
| cmd < file1 > file2 | cmd命令以fiel1文件作为标准输入，以file2文件作为标准输出 |
| cmd < file          | cmd命令以file文件作为标准输入                           |
| cmd << delimiter    | 从标准输入中读入，直到遇到delimiter分界符               |

### 绑定重定向

| 命令     | 描述                            |
| -------- | ------------------------------- |
| cmd >& m | 把标准输出重定向到文件描述符m中 |
| cmd <&-  | 关闭标准输入                    |
| cmd 0>&- | 关闭标准输入                    |

## 重定向的一些高级用法

### 重定向标准错误

**例1**：

如果指令执行出错，将错误的信息重定向到空设备。

```shell
# 原始输出
cat a
cat: a: 没有那个文件或目录
# 重定向到空设备
cat a 2>/dev/null
```

**例2**：

将指令执行的标准输出和标准错误重定向到指定文件。

``` shell
# 原始输出
cat a test/test1.txt 
cat: a: 没有那个文件或目录
1
2
3
4
,
1
2
3
4
# 重定向到文件中
cat a test1.txt >out.put 2>&1
cat out.put 
cat: a: 没有那个文件或目录
1
2
3
4
,
1
2
3
4
```