0

I have a simple bash script to control Amazon AWS uploads and downloads. The uploading and downloading works fine. But sometimes, I have a poor internet connection and I want to cancel the AWS activity. However, when I click on the cancel button (zenity progress dialog) the AWS process continues and continues (for minutes)... The only way I can kill the AWS process is to go to the terminal and execute "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)

I understand that when I depress the cancel pb that it should kill the process. Is there someway that I can force this to happen?

daniel
  • 13
  • 2
  • The problem is that the `aws` and everything else in the `while` loop don't know that `zenity` is closed until they try to write to stdout. As soon as they do that they'll get a SIGPIPE and likely exit – Eric Renouf Jun 12 '17 at 17:46
  • Hmm .. As you can see in my code, I am capturing the AWS output in a log file. The data is regularly updated every partial second as each file as transferred (for several hundred files). So I would expect AWS to shutdown in less than a second after receiving the SIGPIPE. Am I missing something? – daniel Jun 13 '17 at 03:15
  • because you are writing to the file instead of stdout you won't get a SIGPIPE. You'll only get that when you try to write to the pipe, i.e., stdout – Eric Renouf Jun 13 '17 at 09:55
  • So, I am stll looking for a solution. The AWS command, as you can see, is writing to standard out to the "tr" command. Is that not sufficient? If not is there another method to achieve the desired effect ... maybe with tee or something else? – daniel Jun 13 '17 at 20:13
  • The fact that ends with `> "$last_log_file"` prevents anything on that line from writing to `stdout`. If you don't mind the clutter you could force it to write to stdout by using `| tee "$last_log_file"` instead so it would go both to the file and to the pipe, and then you'd get the SIGPIPE error and break, but probably only once it finished that `aws` command (or whenever the output buffer fills) – Eric Renouf Jun 13 '17 at 20:15
  • BTW, [here](http://bernaerts.dyndns.org/linux/331-linux-cancel-zenity-progress-dialog-right-way) is a page that tries to solve this problem. It pretty much does the `kill` command similar to yours when it notices `zenity` has exited. I don't know that I think it's the "right way" as the article claims (it has some pretty questionable parts) but it does suggest what you're doing might be the quickest path to getting `aws` to exit when you want it to – Eric Renouf Jun 13 '17 at 20:35
  • Maybe you can profit from the answer I gave on https://stackoverflow.com/questions/44607387/zenity-auto-kill-killing-a-subshell-does-not-kill-its-child-processes – Francesco Potortì Jun 26 '20 at 11:54
  • Maybe you can profit from the answer I gave on https://stackoverflow.com/questions/44607387/zenity-auto-kill-killing-a-subshell-does-not-kill-its-child-processes – Francesco Potortì Jun 26 '20 at 11:55
  • I think that you could benefit from this answer of mine: https://stackoverflow.com/questions/44607387/zenity-auto-kill-killing-a-subshell-does-not-kill-its-child-processes – Francesco Potortì Jun 26 '20 at 13:58

1 Answers1

0

Thanks to Eric's reply, I now have a solution. The key was to add the '&' at the end of the zenity command in order to run a parallel process..

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

And then to add some code to detect that the zenity pid has disappeared (because it was cancelled). Once it is detected that the zenity pid has gone, the killall command is used to kill aws

Some sample code:

    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 returns an exit code 137 which means that the container received a SIGKILL signal

daniel
  • 13
  • 2