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为空(没错误)。