diff --git a/homebrew/README.md b/homebrew/README.md index 46a8206..5bfbe77 100644 --- a/homebrew/README.md +++ b/homebrew/README.md @@ -325,6 +325,7 @@ brew upgrade --cask --greedy visual-studio-code ## 注意事项 - 脚本启用了 `set -euo pipefail`,但 Formula/Cask 升级阶段会捕获错误、继续隔离其他失败项,并在最后统一返回状态。 +- 交互式终端中直接保留 Homebrew 的 TTY 输出,因此 Formula/Cask 下载会显示原生实时进度;输出被重定向或用于 CI 时会自动回退到按行输出。 - `brew upgrade --cask --greedy` 可能退出正在运行的 GUI 应用,建议先保存重要工作。 - 不建议日常启用 `HB_CASK_FORCE=1`;它会允许 Homebrew 覆盖已有 Cask 文件。 - 远程启动器属于“下载后执行”模式,只应从可信仓库使用。 diff --git a/homebrew/brew-upgrade-manager.sh b/homebrew/brew-upgrade-manager.sh index 36cbd07..4218737 100644 --- a/homebrew/brew-upgrade-manager.sh +++ b/homebrew/brew-upgrade-manager.sh @@ -573,7 +573,14 @@ colorize_brew_output() { run_brew_colored() { local pipeline_status=() - # 管道输出时禁用 Homebrew 自带的不完整配色,再统一按语义着色。 + # Homebrew 只有在 stdout 连接 TTY 时才会让 curl 显示动态下载进度。 + # 交互式终端中保留原始文件描述符,并使用 Homebrew 原生配色。 + if [[ -t 1 ]]; then + brew "$@" + return $? + fi + + # 非交互式输出无法显示动态进度,继续按行进行语义着色。 if env -u HOMEBREW_COLOR brew "$@" 2>&1 | colorize_brew_output; then return 0 fi @@ -697,17 +704,26 @@ run_brew_with_retries() { fi : > "$ACTIVE_LOG_FILE" - if env -u HOMEBREW_COLOR brew "$@" 2>&1 | tee "$ACTIVE_LOG_FILE" | colorize_brew_output; then - status=0 + if [[ -t 0 && -t 1 && -t 2 && "$(uname -s 2>/dev/null || true)" == "Darwin" && -x /usr/bin/script ]]; then + # BSD script 为 brew 分配伪终端:既保留实时进度,又记录完整输出供错误分类。 + if /usr/bin/script -q -e "$ACTIVE_LOG_FILE" brew "$@"; then + status=0 + else + status=$? + fi else - pipeline_status=("${PIPESTATUS[@]}") - status="${pipeline_status[0]}" - if ((${pipeline_status[1]:-0} != 0)); then - print_error "failed to write retry log." - status="${pipeline_status[1]}" - elif ((${pipeline_status[2]:-0} != 0)); then - print_error "failed to colorize Homebrew output." - status="${pipeline_status[2]}" + if env -u HOMEBREW_COLOR brew "$@" 2>&1 | tee "$ACTIVE_LOG_FILE" | colorize_brew_output; then + status=0 + else + pipeline_status=("${PIPESTATUS[@]}") + status="${pipeline_status[0]}" + if ((${pipeline_status[1]:-0} != 0)); then + print_error "failed to write retry log." + status="${pipeline_status[1]}" + elif ((${pipeline_status[2]:-0} != 0)); then + print_error "failed to colorize Homebrew output." + status="${pipeline_status[2]}" + fi fi fi