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

点击Zenity进度窗口取消后,如何终止Bash脚本中的Ghostscript进程?

解决Ghostscript与Zenity进度条配合时,取消窗口后GS进程仍运行的问题

当你用管道将gs与zenity --progress连接时,点击取消按钮后zenity会退出,但gs进程会继续在后台运行——这是因为管道中的两个进程相互独立,zenity退出仅会关闭管道的输出端,gs不会自动终止,仍会完成PDF压缩。要解决这个问题,需要在zenity被取消时主动终止对应的gs进程。

可行方案:跟踪GS进程PID并在取消时终止

通过记录gs的进程ID(PID),在检测到zenity因取消退出(退出码为1)时,调用kill命令终止该gs进程。示例代码如下:

# 启动GS进程并通过管道连接到Zenity,将整个作业放入后台
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$DESTINO.pdf" "$FILE" | zenity --progress --title="Processando" --auto-close --width=220 --text="Comprimindo PDF" --pulsate --percentage=0 &

# 通过父进程PID查找GS的进程ID
GS_PID=$(pgrep -P $!)

# 等待Zenity进程结束,获取其退出状态
wait $!
ZENITY_EXIT_CODE=$?

# 如果Zenity是被取消退出,终止GS进程并退出脚本
if [ "$ZENITY_EXIT_CODE" -eq 1 ]; then
    kill "$GS_PID" 2>/dev/null
    exit 1
fi

方案说明

  1. 后台运行管道作业:将gs | zenity整体放到后台(&),便于后续获取作业关联的进程ID。
  2. 定位GS进程:用pgrep -P $!查找父进程为当前后台作业PID的进程,精准定位到gs进程。
  3. 检测取消操作:wait $!等待zenity结束,获取其退出码——zenity被取消时退出码为1,正常完成时为0。
  4. 主动终止GS:一旦检测到取消操作,立即调用kill终止gs进程,避免其继续占用资源。

替代方案:使用Bash协同进程(coproc)

Bash的coproc可以更清晰地管理协同进程,直接获取gs的PID:

# 启动GS作为协同进程
coproc GS {
    gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile="$DESTINO.pdf" "$FILE"
}

# 将GS的输出导向Zenity进度条
zenity --progress --title="Processando" --auto-close --width=220 --text="Comprimindo PDF" --pulsate --percentage=0 <&"${GS[0]}"

# 获取Zenity退出码
ZENITY_EXIT_CODE=$?

# 取消时终止GS进程
if [ "$ZENITY_EXIT_CODE" -eq 1 ]; then
    kill "${GS_PID}"
    exit 1
fi

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:35:12