Skip to main content

Linux 重定向与管道

Linux 输入输出重定向

在 Linux 中,输入输出重定向是命令行操作的超实用技能。基于 stdin、stdout 和 stderr 的基础,重定向能让你控制数据的流向,比如把命令的输出保存到文件,或者从文件读取输入。

1. 什么是重定向?

重定向就是改变 Linux 命令默认的输入输出行为。正常情况下:

  • stdin(标准输入)来自键盘。
  • stdout(标准输出)和 stderr(标准错误)显示在终端。

通过重定向,你可以:

  • 让 stdin 从文件读取,而不是键盘。
  • 让 stdout 或 stderr 写入文件,而不是显示在屏幕上。

重定向用符号 >(输出)、<(输入)和一些变种来实现,下面一步步看。

2. 输出重定向:把 stdout 写入文件

最常用的重定向是把命令的 stdout 保存到文件,用 > 符号。比如:

ls /etc > output.txt

这行命令会把 ls /etc 的输出(目录内容)写入 output.txt,终端不会显示任何东西。

  • 覆盖写入>> 会覆盖目标文件。如果 output.txt 已经存在,内容会被清空再写入。
  • 追加写入>>:如果不想覆盖,而是追加到文件末尾,用 >>
echo "More text" >> output.txt

这会把 "More text" 追加到 output.txt 末尾。

试试看:

echo "First line" > test.txt
echo "Second line" >> test.txt
cat test.txt

输出会是:

First line
Second line

3. 输出重定向:处理 stderr

默认情况下,> 只重定向 stdout,stderr 还是会显示在终端。比如:

ls /etc /notexist > output.txt

/etc 的内容(stdout)会写入 output.txt,但错误信息(stderr)还是会显示在终端:

ls: cannot access '/notexist': No such file or directory

如果想重定向 stderr,用文件描述符 2

ls /etc /notexist 2> error.txt

这会把 stderr(错误信息)写入 error.txt,而 stdout 仍显示在终端。

想同时重定向 stdout 和 stderr 到不同文件:

ls /etc /notexist > output.txt 2> error.txt
  • output.txt 得到 /etc 的内容(stdout)。
  • error.txt 得到错误信息(stderr)。

4. 合并 stdout 和 stderr

有时候你想把 stdout 和 stderr 都存到同一个文件。可以用 2>&1 把 stderr 重定向到 stdout 的目标:

ls /etc /notexist > output.txt 2>&1

这里:

  • > 把 stdout 送到 output.txt
  • 2>&1 把 stderr 也送到 stdout 的目标(即 output.txt)。

结果是 output.txt 包含了所有输出和错误信息。

还有个更简洁的写法(bash 4.0+):

ls /etc /notexist &> output.txt

&>> output.txt 2>&1 的简写,效果一样。

5. 输入重定向:从文件读取 stdin

输入重定向用 < 符号,让命令从文件读取输入,而不是键盘。比如:

cat < input.txt

假设 input.txt 包含:

Hello
World

运行后,cat 会从 input.txt 读取内容并输出到 stdout(显示在终端)。

另一个常见场景是用 read 命令:

read line < input.txt
echo "First line: $line"

这会读取 input.txt 的第一行存到变量 line,然后输出。

6. Here Document:多行输入重定向

有时候你想直接在命令行提供多行输入,可以用 Here Document<<)。格式是:

cat << EOF
Line 1
Line 2
Line 3
EOF
  • << EOF 告诉 cat 从接下来几行读取输入,直到遇到 EOF(可以是任意字符串,EOF 只是惯例)。
  • 运行后,cat 会把 Line 1Line 3 输出到 stdout。

你也可以把 Here Document 存到文件:

cat << EOF > output.txt
Line 1
Line 2
EOF

这会把两行内容写入 output.txt

7. 结合输入和输出重定向

输入和输出重定向可以一起用。比如:

grep "pattern" < input.txt > output.txt
  • < input.txt:让 grepinput.txt 读取输入。
  • > output.txt:把 grep 的输出写入 output.txt

如果想重定向 stderr 也一起处理:

grep "pattern" < input.txt > output.txt 2> error.txt

8. /dev/null:丢弃输出

有时候你不想看到命令的输出(比如只关心命令是否成功),可以用 /dev/null,它就像个“黑洞”,吞掉所有丢给它的数据:

ls /notexist 2> /dev/null

这会丢弃 stderr 的错误信息,终端啥也不会显示。

丢弃 stdout 和 stderr:

ls /etc /notexist &> /dev/null

9. 实际例子:综合运用

来个综合例子感受一下:

cat < input.txt > output.txt 2> error.txt

假设 input.txt 不存在:

  • error.txt 会包含错误信息:cat: input.txt: No such file or directory
  • output.txt 不会被创建(因为没 stdout 输出)。

再试个带 Here Document 的:

grep "test" << EOF > result.txt 2> error.txt
This is a test line
Another line
EOF
  • result.txt 会包含 This is a test line(stdout)。
  • error.txt 为空(没错误)。