Skip to content

Instantly share code, notes, and snippets.

@gibatronic
Created October 26, 2018 12:58
Show Gist options
  • Save gibatronic/44faf43e260ec6a4d2daadcdce6aaaa0 to your computer and use it in GitHub Desktop.
Save gibatronic/44faf43e260ec6a4d2daadcdce6aaaa0 to your computer and use it in GitHub Desktop.

Revisions

  1. gibatronic created this gist Oct 26, 2018.
    13 changes: 13 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    # Proper job control in Bash scripts

    Simple example of how to properly launch background jobs and then gracefully terminate them.

    ## Gotchas

    1. We could trap only the `EXIT` signal, but then after killing workers we get an unwanted "Terminated" message.
    2. In worker scripts, we must call `exit` when cleaning, to break out of the infinite loop
    3. After killing a worker, we still have to wait for them to gracefully terminate.

    ## Further reading

    * [Job Control Commands](http://www.tldp.org/LDP/abs/html/x9644.html)
    23 changes: 23 additions & 0 deletions main
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    #!/usr/bin/env bash

    clean() {
    echo
    kill $(jobs -pr)
    wait
    echo 'main clean'
    }

    main() {
    local self="$0"
    local base="$(dirname "$self")"

    trap 'clean' 'SIGINT' 'SIGTERM'

    "$base/worker" 'A' &
    "$base/worker" 'B' &
    "$base/worker" 'C' &

    wait
    }

    main "$@"
    21 changes: 21 additions & 0 deletions worker
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    #!/usr/bin/env bash

    clean() {
    local name="$1"

    echo "worker $name clean"
    exit 0
    }

    main() {
    local name="$1"

    trap "clean '$name'" 'SIGINT' 'SIGTERM'

    while true; do
    sleep "$(($RANDOM % 5 + 1))"
    echo "worker $name tick"
    done
    }

    main "$@"