主题
  • 默认模式
  • 浅蓝色模式
  • 淡绿色模式
  • 深夜模式

Shell 输入/输出重定向

大多数 UNIX 系统命令通过标准输入(stdin)接收数据,并将结果通过标准输出(stdout)输出。默认情况下,标准输入关联至用户终端接口(通常是键盘输入),标准输出也指向同一终端设备(通常为显示输出)。

命令执行过程中的常规信息与结果均经由标准输出流传递,而错误信息则通过独立的标准错误流(stderr)输出,其默认输出设备同样为用户终端。

文件描述符 (File Descriptors)

✅ Shell 用文件描述符来代表每个数据流,最基础的三个是:

  • 0 - 标准输入 (stdin): 默认是键盘输入。
  • 1 - 标准输出 (stdout): 默认输出到终端屏幕。
  • 2 - 标准错误 (stderr): 默认输出到终端屏幕(用于错误消息)。

重定向的本质就是改变这些数据流的来源和目标。


Shell 输出重定向

1. 重定向标准输出 (>1>)

将命令的正常输出(stdout)发送到一个文件中。如果文件已存在,则会覆盖原有内容。

bash
复制
# 将 ls 命令的结果输出到 file.txt 文件,而不是屏幕
ls -l > file.txt

# 等价写法,1 代表标准输出,可以省略
ls -l 1> file.txt

2. 追加标准输出 (>>)

将命令的正常输出(stdout)追加到一个文件的末尾。如果文件不存在,则创建它。

bash
复制
# 将日期信息追加到 log.txt 文件的末尾
date >> log.txt

3. 重定向标准错误 (2>)

将命令的错误信息(stderr)发送到一个文件中。

bash
复制
# 尝试列出一个不存在的文件,将错误信息保存到 errors.log
ls /nonexistent_directory 2> errors.log

4. 重定向标准输出和标准错误

有几种方法可以同时重定向 stdout 和 stderr。

方法一:分别重定向到不同文件

bash
复制
# 正常输出到 output.txt,错误输出到 error.txt
command > output.txt 2> error.txt

方法二:重定向到同一个文件 (&>2>&1)

bash
复制
# 推荐写法:Bash 中的简便方法
command >> output_and_error.txt

# 传统写法:先将 stdout 重定向到文件,然后告诉 stderr 去模仿 stdout(即也去同一个文件)
command > output_and_error.txt 2>&1
# 注意:`2>&1` 的顺序很重要,必须写在后面。

方法三:追加到同一个文件

bash
复制
command &>> output_and_error.txt
# 或
command >> output_and_error.txt 2>&1

5. 丢弃输出(重定向到空设备) (/dev/null)

/dev/null 是一个特殊的系统文件,它会丢弃所有写入它的数据。常用于忽略不需要的输出(尤其是错误信息)。

bash
复制
# 只关心命令是否成功执行,不关心任何输出
ping -c 1 google.com > /dev/null 2>&1

# 如果只想丢弃错误信息,保留正常输出
command 2> /dev/null

Shell 输入重定向

1. 重定向标准输入 (<)

让命令从指定的文件中读取输入,而不是从键盘读取。

bash
复制
# 计算 file.txt 文件的行数
# 这两种写法效果一样,但原理不同
wc -l < file.txt     # 使用输入重定向
wc -l file.txt       # wc 命令直接接收文件名作为参数

# 一个更典型的例子:排序
sort < unsorted_list.txt > sorted_list.txt

2. 内联输入重定向 (<<)

也称为 Here Document。它允许你在脚本中直接嵌入输入数据,直到遇到指定的 “结束标记符”。

bash
复制
# 让 cat 命令读取直到遇到 EOF 标记之间的所有内容
cat << EOF
这是第一行内容。
这是第二行内容。
这是最后一行,遇到 EOF 后输入就结束。
EOF
# 输出:
# 这是第一行内容。
# 这是第二行内容。
# 这是最后一行,遇到 EOF 后输入就结束。

3. 内联输入重定向(忽略制表符)(<<-)

<<类似,但会忽略输入内容中的前导制表符 (Tab)。这使得在 Shell 脚本中编写多行内容时,代码格式可以保持整齐。

bash
复制
# 在脚本中这样写很美观,但内容本身没有前导的 Tab
if true; then
    cat <<- EOF
    	这一行开头有一个 Tab,但会被 shell 忽略。
    	这一行也是。
    EOF
fi

重定向顺序与文件描述符操作

你可以操作其他文件描述符(如 3, 4, 5...)来进行更复杂的重定向。

bash
复制
# 创建一个自定义的文件描述符 3 并关联到文件
exec 3> custom_output.txt

# 向文件描述符 3 写入内容
echo "This goes to custom_output.txt" >&3

# 关闭文件描述符 3
exec 3>&-

Shell 重定向操作符

Shell 重定向操作符用于控制命令的输入和输出流向,可以将输出重定向到文件或设备,或者从文件获取输入。

✅ 下表列出了常用的重定向操作符及其用法:

符号 作用 示例
command > file 将 stdout 覆盖重定向到 file ls > output.txt
command >> file 将 stdout 追加重定向到 file date >> log.txt
command 2> file 将 stderr 覆盖重定向到 file ls bad_dir 2> error.log
command 2>> file 将 stderr 追加重定向到 file cmd 2>> debug.log
command &> file 将 stdout 和 stderr 都重定向到 file cmd &> all_output.txt
command > file 2>&1 同上,传统写法 cmd > file 2>&1
command < file 从 file 获取 stdin sort < input.txt
command << delimiter 从标准输入读入,直到遇到 delimiter cat << EOF
command <<- delimiter 同上,但会忽略输入中的前导制表符 cat <<- EOF
command > /dev/null 丢弃 stdout cmd > /dev/null
command 2> /dev/null 丢弃 stderr cmd 2> /dev/null
command > /dev/null 2>&1 丢弃所有输出 cmd > /dev/null 2>&1


评论区 0
发表评论