Running multiple instances of shell script?

Is it possible to run multiple instances of a shell script simultaneously from within one applescript? I know applescript is essentially not multi-threaded. When you run a shell script from within an applescript, the applescript waits for the shell-script to finish before continuing. But I was wondering if there is some sort of hack around this.

You can do it like the following, but with this approach you won’t directly get any output from the command. To get output you would have to write it to a file. Then in your script you could check for the PID of the process. WHen you can no longer find the PID you know that the process is finished then could could read the contents of the file to get the output.

-- AppleScript's do shell script holds the process' stdout and stderr hooks waiting for the output of the command. That's why it appears to hang - it's doing what it's designed to do.

-- The solution is simple - you redirect stderr and stdout to some other location and send the shell process to the background
-- the > /dev/null redirects the process' stdout to /dev/null (you can use some other file path if you want to capture its output). 2>&1 redirects stderr to the same place as stdout (in this case, /dev/null) and the trailing & sends the process to the background.

-- You'll find that this effectively returns control back to your script while the shell process runs in the background

-- add "echo $!" to the end of the command to have the PID of the spawned process returned to applescript

do shell script "/bin/sleep 5 > /dev/null 2>&1 &"
beep

-- to get the pid of the process use "echo $1"
do shell script "/bin/sleep 5 > /dev/null 2>&1 & echo $!"
set the_pid to the result

Thanks, that seems to work.

How would you normally check for the PID? I tried with system events, but without luck.

A shell script that someone posted here doesn’t work that well. Rather than returning “false” if the process isn’t running anymore it creates an error. So for now, I’m just using a try-block.

try
	set processExists to ((count of paragraphs in (do shell script "ps -p " & the_PID)) > 1)
on error
	set processExists to false
end try

You’re welcome. I use this code…

set thePID to do shell script "/bin/sleep 2 > /dev/null 2>&1 & echo $!"
set pidSearch to do shell script "ps ax | grep " & thePID & " | grep -v grep | awk '{ print $1 }'"

-- If pidSearch is "" then the process is finished.
-- If pidSearch is the pid number then the process is still running.
if pidSearch is "" then
	return "process is finished"
else if pidSearch is thePID then
	return "process is still running"
else
	return "error"
end if

Thanks. That works a treat. No idea why though, one of these days I will have to learn shell scripting.