Bash脚本实现求助:并行进程后台运行与日志输出问题
满足需求的Bash脚本实现方案
需求说明
脚本整体需求
- 并行启动多个进程
- 等待所有进程执行完毕后再继续自身执行
单个进程需求
- 执行耗时较长
- 日志需同时输出至子
gnome-terminal窗口和独立日志文件(与其他进程及父脚本终端、日志文件区分) - 关闭子
gnome-terminal窗口或在窗口按Ctrl+C后,进程仍需继续运行并输出日志至对应文件
用户的尝试代码
nohup gnome-terminal --wait -- bash -c "cd /home;find . -name "foo*" | tee /home/$USER/log-home.txt" & nohup gnome-terminal --wait -- bash -c "cd /home/$USER; find . -name "foo*" | tee /home/$USER/log-$USER.txt" & wait; echo "Finished";
当前代码的问题
- 关闭子
gnome-terminal窗口后,对应进程停止输出日志:因为find进程是gnome-terminal启动的bash进程的子进程,关闭终端时bash会收到SIGHUP信号并转发给find,导致find终止。 - 关闭所有子
gnome-terminal窗口后,父脚本直接继续执行后续命令:--wait参数让gnome-terminal直到其启动的bash进程退出才结束,关闭终端会触发bash退出,因此nohup gnome-terminal...的后台进程会结束,wait命令认为所有后台任务完成,进而执行后续的echo。
解决方案代码
# 定义启动任务的函数:启动后台任务+对应的日志查看终端 start_task() { local task_cmd="$1" local log_file="$2" local window_title="$3" # 启动后台任务,脱离终端控制,输出写入日志文件 nohup bash -c "$task_cmd" > "$log_file" 2>&1 & local task_pid=$! # 启动gnome-terminal,实时跟踪日志文件内容 gnome-terminal --title="$window_title" -- bash -c "tail -f '$log_file'; exit" & # 返回后台任务的PID,供父脚本等待 echo "$task_pid" } # 启动多个任务,收集每个任务的PID task_pids=() task_pids+=($(start_task "cd /home; find . -name \"foo*\"" "/home/$USER/log-home.txt" "Home目录查找任务")) task_pids+=($(start_task "cd /home/$USER; find . -name \"foo*\"" "/home/$USER/log-user.txt" "用户目录查找任务")) # 等待所有后台任务执行完毕 wait "${task_pids[@]}" echo "所有任务已执行完成"
方案关键点说明
- 后台任务独立运行:实际的耗时任务(如
find)通过nohup在后台启动,完全脱离终端控制,即使关闭gnome-terminal窗口,任务仍会继续运行并写入日志文件。 - 终端实时查看日志:
gnome-terminal窗口中运行tail -f命令实时读取日志文件,实现日志同步显示;关闭终端仅终止tail进程,不影响后台任务。 - 父脚本等待真实任务:父脚本收集的是后台任务进程的PID,而非
gnome-terminal进程的PID,wait命令会等待所有任务真正执行完毕后才继续后续逻辑,避免提前结束。
内容的提问来源于stack exchange,提问作者goahead97
相关产品推荐
相关产品推荐

