shellkilldash-shell

"kill %1" fails and prints "No such process" inside script


I am currently using dash as main shell.
I tried to write a little function that should imitate wait, but with some text.

Here's a minimal, working code:

#!/bin/dash

wait() {
  echo Waiting...
  local pid="${1}"; shift
  local delay=.250
  while kill -0 "${pid}" 2>/dev/null; do
    echo Still waiting...
    sleep "${delay}"
  done
  echo Resuming
}

main() {
  sleep 3 &
  wait %1
}

main

If you copy-paste it in a dash shell you can see the code works just fine.
Anyway, if you try to save it in a file, it does not.

After some troubleshooting I've done I found out that deleting 2>/dev/null, you can see an error message: kill: No such process, but using command wait "${pid}" it just waits for it.

So for example:

#!/bin/dash

wait() {
  echo Waiting...
  local pid="${1}"; shift
  command wait "${pid}"
  echo Resuming
}

main() {
  sleep 3 &
  wait %1
}

main

works fine as a file script, too.

I am not sure where/what I am wrong in this piece of code and some things I tried didn't help.

Among the trials I tried to convert %1 to its pid, but jobs -p %1 in a subshell (such as var="$(jobs -p %1)") fails badly.

Any tip?


Solution

  • Job control is disabled in non-interactive shells. Enable it with set -m, or by appending -m to the shebang, and it'll work.

    Example:

    $ dash -c 'sleep 1 & kill %1 && echo success'
    dash: 1: kill: No such process
    
    $ dash -m -c 'sleep 1 & kill %1 && echo success'
    success