重定向

输出流格式分别有 n>n>>>&n>>&n<,n 存在以下值
1:stdout 标准输出流
2:stderr 错误输出流
0:stdin 标准输入流

汇总

  • >&1 重定向输出到 stdout 标准流
  • >&2 重定向输出到 stderr 错误流
  • > $filepath stdout 标准流重定向输出到 $filepath 文件
  • 2> $filepath stderr 错误流重定向输出到 $filepath 文件
  • > $filepath 2>&1 stdout、stderr 标准流和错误流重定向到 $filepath 文件
  • > /dev/null 忽略 stdout 标准流输出到控制台
  • 2> /dev/null 忽略 stderr 错误流输出到控制台
  • > $filepath 2>&1 等价于 &> $filepath (忽略全部 &> /dev/null)

重定向输出流 >、>>、2>、2>> 和 2>&1、2>>&1,常用的是 >、>>、2>、2>&1,假设存在 file.txt 文件,文件内容如下所示。

  1. Java is an amazing development language

1. >

标准输出流,表示内容全覆盖,> file.txt,若 file.txt 原本存在内容,则进行覆盖处理。

$ echo "Java frameworks: Spring / Hibernate" > file.txt

$ cat file.txt
Java frameworks: Spring / Hibernate

2. >>

标准输出流,表示内容追加,>> file.txt,若 file.txt 原本存在内容,则追加内容处理。

$ echo "Java frameworks: Spring / Hibernate" >> file.txt

$ cat file.txt
Java is an amazing development language
Java frameworks: Spring / Hibernate

3. 2>

错误输出流,将错误信息以覆盖的形式重定向输出到指定文件,如下例所示。

$ grep -i 'hello' *
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息
helloworld.cpp:  cout << "Hello World!" << endl; # 正常输出
$ grep -i 'hello' * 2> test.output
helloworld.cpp:  cout << "Hello World!" << endl;

$ cat test.output
grep: C++Demo: Is a directory
grep: C-demo: Is a directory

可以发现 test.output 文件仅包含错误流信息,如果我们只要正常部分的重定向输入,那么还是得使用 > 和 >>。

$ grep -i 'hello' * > test.output
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息

$ cat test.output
helloworld.cpp:  cout << "Hello World!" << endl;

看到命令的输出内容和 test.output 内容与 2> 方式的完全相反。

4. 2>>

错误输出流,将错误信息以追加的形式重定向输出到指定文件,如下例所示。

$ grep -i 'hello' * 2>> test.output
helloworld.cpp:  cout << "Hello World!" << endl;

$ grep -i 'hello' * 2>> test.output
helloworld.cpp:  cout << "Hello World!" << endl;

$ cat test.output
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息

看到我们如果执行两次 2>> 操作,则 test.output 会存在重复内容。

5. 2>&1

将错误流输出到标准流中,譬如,我们将标准流和错误流重定向到同一个文件,参数下例所示。

$ grep -i 'hello' * > test.output 2>&1

$ cat test.output
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息
helloworld.cpp:  cout << "Hello World!" << endl;

6. &>

其实我们还有一个更直接简单的写法代替 > filename 2>&1,那就是 &>,如下例所示。

$ grep -i 'hello' * &> test.output

$ cat test.output
grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息
helloworld.cpp:  cout << "Hello World!" << endl;

7. /dev/null

这是一个空文件,可以忽略输出流,如过滤标准流输出,参考下例所示。

$ grep -i 'hello' * > /dev/null

grep: C++Demo: Is a directory   # 错误信息
grep: C-demo: Is a directory    # 错误信息

过滤错误流输出,参考下例所示。

$ grep -i 'hello' * 2> /dev/null

helloworld.cpp:  cout << "Hello World!" << endl;

特别提醒

Java 中如何区分 stdout 标准流和 stderr 错误流,分别对应 System.outSystem.err