do shell script: Get PID of new process

What is the easiest way to get hold of the process ID (pid) of the process created with a “do shell script” command? Are there better ways than “awking” the output of ps?

As documented on Apple’s Technote on ‘do shell script’:

1 Like

Many thanks for the above tip.

However my command is a shell script which calls other commands. For testing it is simply:

#!/bin/sh sleep 15
Now, following the earlier advice I can get the PID of the process running the shell script. I can kill the shell process but the sleep process is left behind :frowning:

My AppleScript code looks like:

do shell script "myscript > /dev/null 2>&1 & echo $!"
set pid to theresult
do shell script "kill -9 " & pid

Any tips on how to kill the sleep process?

do shell script "myscript > /dev/null 2>&1 & echo $!"
set pid to theresult
do shell script "kill -9 -" & pid

In answer to my own question. The addition of a “-” before the PID in the kill command kills the choosen processes and all processes in the same group. Problem solved.

I tried adding the dash (-) to my code and it didn’t seem to stop the sleep process that my shell script had started. The following did work:

kill -9 `ps -awwx | grep [s]leep | grep "??" | awk '{ print $1 }'`

This looks for a sleep process with no owner (I’d just killed it) and kills it.

On another front, I can’t seem to start a background process (process_name &) from Applescript or AS Studio without it hanging. Just doesn’t work.

do shell script "sleep 15 &"
display dialog "Hi"

This waits 15 seconds before displaying the dialog. Any ideas?

The same technote mentioned above discusses this one, too. The issue is that the ‘do shell script’ command hooks into the stdout and stderr of the process you call. ‘do shell script’ will wait for these to close (typically when the process terminates) before continuing.

The solution is to suppress stdout and stderr:

do shell script "sleep 10 >/dev/null 2>&1 &"
display dialog "Hi!"

The ‘>/dev/null 2>&1’ suppresses stdout and stderr so that ‘do shell script’ doesn’t wait.

Thanks, Camelot.

I’d seen the ‘no output redirect’ but didn’t understand what was going on. The explanation helped.

Just curious, why do you need all this > /dev/null 2>&1? I am using your example with caffeinate (to prevent the computer from going to sleep while executing a script that takes a long time to finish) that doesn’t output anything but if I remove these output redirects your example fails (it works fine if I include them).

Camelot answered that in the last line of his post.

The ‘>/dev/null 2>&1’ suppresses stdout and stderr so that ‘do shell script’ doesn’t wait.

the part ‘>/dev/null’ redirect standard output to null, which throws away any output.
the part '2>&1’ redirects standard error to wherever standard output is going. (i.e. same place)