| 1 | #!/usr/bin/env bash
 | 
| 2 | #
 | 
| 3 | # Compare the output of "jobs" in different shells
 | 
| 4 | #
 | 
| 5 | # Usage:
 | 
| 6 | #   $SH demo/jobs-builtin.sh <function name>
 | 
| 7 | 
 | 
| 8 | set -o nounset
 | 
| 9 | #set -o pipefail
 | 
| 10 | set -o errexit
 | 
| 11 | 
 | 
| 12 | # Notes:
 | 
| 13 | # - the formats are consistent, because it's specified by POSIX
 | 
| 14 | #   - they use [1] [2] [3] 
 | 
| 15 | #   - + is the default job for 'fg' and 'bg', which is also %%
 | 
| 16 | #   - - is the job that would become the default, which is also %-
 | 
| 17 | #
 | 
| 18 | # "[%d] %c %s %s\n", <job-number>, <current>, <state>, <command>
 | 
| 19 | #
 | 
| 20 | # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/jobs.html
 | 
| 21 | #
 | 
| 22 | # TODO: YSH should print this as J8!   So you can parse it.
 | 
| 23 | #
 | 
| 24 | # - dash is the only shell that doesn't show source code; it just shows | for pipe
 | 
| 25 | # - mksh has some weird quoting, like \sleep 1
 | 
| 26 | # - mksh and zsh doesn't show trailing &, but bash does
 | 
| 27 | #
 | 
| 28 | 
 | 
| 29 | show_jobs() {
 | 
| 30 |   echo ___
 | 
| 31 | 
 | 
| 32 |   # all shells support this long format which shows components of a pipeline
 | 
| 33 |   #if true; then
 | 
| 34 |   if true; then
 | 
| 35 |     jobs -l
 | 
| 36 |   else
 | 
| 37 |     jobs
 | 
| 38 |   fi
 | 
| 39 | }
 | 
| 40 | 
 | 
| 41 | myfunc() {
 | 
| 42 |   sleep 0.3
 | 
| 43 |   show_jobs
 | 
| 44 | 
 | 
| 45 |   sleep 0.4
 | 
| 46 |   show_jobs
 | 
| 47 | }
 | 
| 48 | 
 | 
| 49 | 
 | 
| 50 | demo() {
 | 
| 51 |   sleep 1 & sleep 2 & 
 | 
| 52 |   show_jobs
 | 
| 53 | 
 | 
| 54 |   # In jobs -l, bash, zsh, and mksh all combine this onto one line:
 | 
| 55 |   # { echo pipe1; sleep 0.5; }
 | 
| 56 | 
 | 
| 57 |   { echo pipe1
 | 
| 58 |     sleep 0.5
 | 
| 59 |   } | tac | wc -l &
 | 
| 60 | 
 | 
| 61 |   show_jobs
 | 
| 62 | 
 | 
| 63 |   myfunc &
 | 
| 64 | 
 | 
| 65 |   # only bash supports wait -n
 | 
| 66 |   if test -n "${BASH_VERSION:-}"; then
 | 
| 67 |     wait -n
 | 
| 68 |     show_jobs
 | 
| 69 |   fi
 | 
| 70 | 
 | 
| 71 |   wait
 | 
| 72 |   show_jobs
 | 
| 73 | 
 | 
| 74 |   ls | wc -l
 | 
| 75 |   show_jobs
 | 
| 76 | }
 | 
| 77 | 
 | 
| 78 | many_jobs() {
 | 
| 79 |   sleep 0.90 &
 | 
| 80 |   sleep 0.91 &
 | 
| 81 |   sleep 0.92 &
 | 
| 82 |   sleep 0.93 &
 | 
| 83 |   sleep 0.94 &
 | 
| 84 |   sleep 0.95 &
 | 
| 85 |   sleep 0.96 &
 | 
| 86 |   sleep 0.97 &
 | 
| 87 |   sleep 0.98 &
 | 
| 88 |   sleep 0.99 &
 | 
| 89 | 
 | 
| 90 |   show_jobs
 | 
| 91 | 
 | 
| 92 |   # Testing this syntax
 | 
| 93 |   # Doesn't work because shells say "job %10 not created under job control"
 | 
| 94 |   # fg %10
 | 
| 95 | 
 | 
| 96 |   wait
 | 
| 97 |   show_jobs
 | 
| 98 | }
 | 
| 99 | 
 | 
| 100 | osh-debug() {
 | 
| 101 |   # lastpipe with 'read'
 | 
| 102 |   { echo x; sleep 0.1; } | sort | read x
 | 
| 103 |   jobs --debug
 | 
| 104 | 
 | 
| 105 |   # no lastpipe
 | 
| 106 |   { echo x; sleep 0.1; } | sort | wc -l
 | 
| 107 |   jobs --debug
 | 
| 108 | }
 | 
| 109 | 
 | 
| 110 | "$@"
 |