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

使用nohup运行脚本时,如何将特定内容同时输出到日志与终端

解决方案

一、先修正原脚本的语法错误

原脚本存在几处语法问题,必须修正才能正常运行:

  • 把大写的 While 改为小写 while(bash 严格区分大小写)
  • for i "${array[@]}" 改为 for i in "${array[@]}"(缺少循环关键字 in)
  • pid="$!" 改为 pid+=("$!")(数组赋值语法错误,否则只会保留最后一个进程ID)

修正后的核心片段:

pid=()
for i in "${array[@]}"; do
     echo starting process for "$i"
     script_A.sh "$i" &
     status_bar $!   # 需要在nohup运行时将该函数输出打印到终端
     pid+=("$!")
done

二、让特定内容同时输出到终端和日志的两种方案

方案1:修改脚本,指定特定内容写入终端

利用 /dev/tty(当前终端设备文件),让status_bar的输出同时写入日志和终端:

方式A:用tee直接分流输出

修改status_bar函数:

status_bar(){
    # 同时输出到stdout(会被nohup写入日志)和终端
    printf "[" | tee -a /dev/tty
    while kill -0 "$1" 2>/dev/null; do
        printf "-" | tee -a /dev/tty
        sleep 1
    done
    printf "] done!\n" | tee -a /dev/tty
}

之后直接运行原nohup命令即可:

nohup myscript.sh &> file.log &

方式B:提前打开终端文件描述符(更高效)

在脚本开头添加:

# 打开终端的文件描述符3,后续直接用>&3输出到终端
exec 3>/dev/tty

然后修改status_bar函数:

status_bar(){
    printf "["
    printf "[" >&3
    while kill -0 "$1" 2>/dev/null; do
        printf "-"
        printf "-" >&3
        sleep 1
    done
    printf "] done!\n"
    printf "] done!\n" >&3
}

同样运行原nohup命令,此时status_bar的内容会同时出现在终端和file.log,其他日志内容仅写入file.log。

方案2:不修改脚本,通过命令行过滤输出

如果不想改动脚本,可以在运行nohup时,用tee把所有输出写入日志,同时用grep过滤出status_bar相关内容显示在终端:

nohup myscript.sh 2>&1 | tee file.log | grep -E '\[|-|\] done!' &
  • 2>&1:把stderr合并到stdout,确保错误信息也写入日志
  • tee file.log:将所有输出写入日志文件
  • grep -E '\[|-|\] done!':只过滤显示status_bar输出的[、-、] done!内容,避免终端被无关日志占满

内容的提问来源于stack exchange,提问作者Ahkam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:43:36