【问题标题】:bash zenity dialog does not kill process when cancel depressedbash zenity 对话框在取消按下时不会终止进程
【发布时间】:2017-06-12 17:36:25
【问题描述】:

我有一个简单的 bash 脚本来控制 Amazon AWS 的上传和下载。上传和下载工作正常。但有时,我的互联网连接很差,我想取消 AWS 活动。但是,当我单击取消按钮(zenity 进度对话框)时,AWS 进程继续并继续(几分钟)......我可以终止 AWS 进程的唯一方法是转到终端并执行“killall -9 aws”

    while [ "$repeat" -eq 0 ]; do
      ...   setup code ...
      aws s3 sync "$dir1" "$dir2" --region us-east-1 --output text --sse --delete  | tr '\r' '\n' > "$last_log_file"
      ...  error code analysis
    done | zenity --progress --title="$title_text" --text="$msg" --pulsate --auto-close
    killall -9 aws # <=== When I depress zenity 'cancel' ... this code never executes !!! (this code was added for debug)

我知道当我按下取消按钮时,它应该终止进程。有什么办法可以强迫这种情况发生吗?

【问题讨论】:

  • 问题是awswhile 循环中的所有其他内容在尝试写入标准输出之前都不知道zenity 已关闭。一旦他们这样做了,他们就会得到一个 SIGPIPE 并可能退出
  • Hmm .. 正如您在我的代码中看到的,我正在日志文件中捕获 AWS 输出。随着每个文件的传输(数百个文件),数据每隔部分秒定期更新一次。所以我希望 AWS 在收到 SIGPIPE 后不到一秒钟就关闭了。我错过了什么吗?
  • 因为您正在写入文件而不是标准输出,所以您不会获得 SIGPIPE。只有当您尝试写入管道时,您才会得到它,即标准输出
  • 所以,我还在寻找解决方案。如您所见,AWS 命令​​正在将标准输出写入“tr”命令。这还不够吗?如果没有,是否有另一种方法可以达到预期的效果......也许用 tee 或其他东西?
  • &gt; "$last_log_file" 结尾的事实阻止了该行的任何内容写入stdout。如果您不介意混乱,您可以使用| tee "$last_log_file" 强制它写入标准输出,这样它就会同时进入文件和管道,然后您会收到 SIGPIPE 错误并中断,但可能只有一旦它完成了aws 命令(或每当输出缓冲区填满)

标签: bash amazon-s3 zenity


【解决方案1】:

感谢 Eric 的回复,我现在有了解决办法。关键是在 zenity 命令的末尾添加 '&' 以运行并行进程..

    done | zenity --progress --title="$title_text" --text="$msg" --pulsate --auto-close &

然后添加一些代码来检测zenity pid已经消失(因为它被取消了)。一旦检测到zenity pid已经消失,就使用killall命令杀死aws

一些示例代码:

    zenity_pid="$(pidof zenity)"
    while [ "$zenity_pid" != '' ]; do
       echo "$(pidof zenity)" | grep -w "$zenity_pid"
       if [ "$?" -eq 0 ]; then
           sleep 2
       else
           killall -9 aws
           zenity_pid=''
       fi
    done
    wait

AWS 返回退出代码 137,表示容器收到 SIGKILL 信号

【讨论】:

    猜你喜欢
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多