714 字
4 分钟
输入输出流重定向

输入输出流重定向#

Terminal window
常见用法:
command > file 2>&1

基础使用#

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以这样写:

Terminal window
$ command 2>file

如果希望 stderr 追加到 file 文件末尾,可以这样写:

Terminal window
$ command 2>>file

2 表示标准错误文件(stderr)。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

Terminal window
$ command > file 2>&1
$ command >> file 2>&1

如果希望对 stdin 和 stdout 都重定向,可以这样写:

Terminal window
$ command < file1 >file2

command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。

标准I/O流介绍#

​ 通常情况下每个程序加载后都会有3个流被fopen——stdin、stdout、stderr,它们是标准C中的FILE*指针。在unix环境对应的文件描述符为0、1、2(宏定义为STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO)。当然,程序退出的时候它们也会被fclose。

​ 不要简单地把stdin视作键盘缓冲区,stdout视作屏幕缓冲区,尽管多数时候确实像这么回事。关键在于unix中的IO重定向,这三个流都可以被重定向到任意的文件或设备中,一切皆文件嘛。

int main(int argc, char* argv[])
{
int a, b;
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n", a, b, a+b);
return 0;
}

上述代码中的执行过程看似是先在命令行下输入两个数字,然后打印出两数之和,但只要动点手脚…

Terminal window
$ echo "1 2" > input.txt
$ cc main.c
# 将stdin重定向到input.txt,将stdout重定向到output.txt
$ ./a.out 0<input.txt 1>output.txt
$ cat output.txt
1 + 2 = 3

可以看到,程序瞬间执行完且并无任何打印,相应的输入输出内容已存放在input.txt和output.txt中。所以:

  • stdin可以是数据、键盘、鼠标、触摸板、终端等任何一种“文件”
  • stdout可以是数据、键盘、鼠标、触摸板、终端等任何一种“文件”
  • stderr可以是数据、键盘、鼠标、触摸板、终端等任何一种“文件”

理解标准IO流的好处能够提升某些应用场景下软件的开发效率,例如我们需要从某个终端输入一些内容,然后将处理结果显示到另一个终端,再把错误日志存储到某个文件,如果能用好标准IO流,不仅可以省去日志管理的开发,还能提高程序的灵活性。

Reference:#

【1】https://www.runoob.com/linux/linux-shell-io-redirections.html

【2】https://zhuanlan.zhihu.com/p/437797951

输入输出流重定向
https://tuoyuangui.github.io/website/posts/typora/linux系统/输入输出流重定向/
作者
椭圆规/tuoyuangui
发布于
2024-06-20
许可协议
CC BY-NC-SA 4.0