You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bash脚本内捕获所有输出到文件并保留终端打印

在Bash脚本内部捕获所有输出到文件并同时终端打印

嘿,这个需求其实挺容易实现的,不用在外部调用时加tee,咱们直接在脚本内部用Bash的进程替换和exec命令就能搞定。下面给你两种实用的方案:

方案一:把标准输出和错误输出合并到同一个日志文件

这种方式适合你想把所有输出(包括git pull的输出和脚本自己的提示)都存在同一个文件里,同时终端正常显示:

#!/bin/bash

# 先定义日志文件的路径,你可以改成自己想要的名字
LOG_FILE="script_run.log"

# 关键一步:用exec把stdout和stderr都重定向到tee进程
# tee会同时把内容输出到终端和追加到日志文件
exec > >(tee -a "$LOG_FILE") 2>&1

# 接下来的所有命令输出都会被自动捕获啦
git pull origin main
echo "Operation took XX minutes"
# 其他命令...

简单解释:

  • > >(tee -a "$LOG_FILE"):把脚本的标准输出(stdout)重定向到tee的进程替换里,tee负责把内容同时打印到终端和追加到日志文件(-a是追加模式,避免每次运行覆盖旧日志)。
  • 2>&1:把标准错误(stderr,比如git的错误提示)重定向到和标准输出一样的地方,这样错误信息也会被tee处理,同时显示在终端和写入日志。

方案二:把标准输出和错误输出分开存到不同文件

如果你想把正常输出和错误输出分别保存,同时终端还是能看到所有内容,可以这么写:

#!/bin/bash

OUT_LOG="normal_output.log"
ERR_LOG="error_output.log"

# 处理stdout:终端+正常日志文件
exec > >(tee -a "$OUT_LOG")
# 处理stderr:终端+错误日志文件,这里要把tee的输出重定向回stderr,保持终端的错误显示样式
exec 2> >(tee -a "$ERR_LOG" >&2)

git pull origin main
echo "Operation took XX minutes"
# 其他命令...

注意事项:

  1. 确保脚本开头是#!/bin/bash,因为进程替换>(...)是Bash的特性,sh(比如Dash)不支持这个语法。
  2. 如果不想追加日志,而是每次运行清空旧日志,去掉tee的-a参数就行。
  3. 脚本里的子shell(比如(cd /tmp && ls))也会继承这个重定向设置,所以子shell里的输出也会被捕获。

内容的提问来源于stack exchange,提问作者Dr. Gianluigi Zane Zanettini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:41:19