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 1
到Line 3
输出到 stdout。
你也可以把 Here Document 存到文件:
cat << EOF > output.txt
Line 1
Line 2
EOF
这会把两行内容写入 output.txt
。
7. 结合输入和输出重定向
输入和输出重定向可以一起用。比如:
grep "pattern" < input.txt > output.txt
< input.txt
:让grep
从input.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
为空(没错误)。