Bash – how to run multiple shell scripts in parallel

bashshell

I have a few test scripts, each of which runs a test PHP app. Each script runs forever.

So, cat.sh, dog.sh, and foo.sh each run a PHP script. Each shell script runs the PHP app in a loop, so it runs forever, sleeping after each run.

I'm trying to figure out how to run the scripts in parallel at the same time. See the output of the PHP apps in the stdout/term window.

I thought, doing something like the following might work:

foo.sh > &2
dog.sh > &2
cat.sh > &2

In a shell script it would be sufficient, but it's not working.

foo.sh, runs foo.php once, and it runs correctly
dog.sh, runs dog.php in a never ending loop. it runs as expected
cat.sh, runs cat.php in a never ending loop
 *** this never runs!!!

It appears that the shell script never gets to run cat.sh. If I run cat.sh by itself in a separate window/term, it runs as expected.

Does anyone have any ideas on how I can get these scripts to run in parallel?

Best Answer

Your current setup is running your commands sequentially. The first one runs, and completes, allowing the second one to start. The second one never ends, so the third one never gets a chance to start.

Try this:

foo.sh >foo.out 2>foo.err &
dog.sh >dog.out 2>dog.err &
cat.sh >cat.out 2>cat.err &

That will tell each command to run in the background, and send their output and error information to files. When a command is run in the background, it detaches from the current session, and allows the next command to run. It's important to put the ampersand (&) as the last character of the line. Otherwise, it might not get recognized correctly.

Alternately, have each of your shell scripts run the associated .php script you're apparently calling with the same semantics as above. In this scenario, your foo.sh might contain:

#!/bin/bash
php foo.php >foo.out 2>foo.err &

Finally, if you need true parallel operation, check out GNU Parallel.

Note: If you really want the output going to the screen/terminal, you can leave off the output redirection:

foo.sh &

Remember, though, that running multiple commands concurrently can cause confusing output (you may now know what output or errors came from which command), and if you logout, the output has nowhere to go.