Continue problem

Hey all. First-time poster, long-time reader

I'm on Mac, and I've written a long script to open up a maximum of 20 Terminal windows and run a subscript with a different input in each of them. When each of these sub-scripts finishes, it changes the value of a variable ("$windows") by -1, which lets the main script know that it can open a new window. It's basically a brute force approach to parallel processing on Mac.

The problem is, when it reaches the max number of windows, it doesn't wait for the "$windows" variable to go down before moving to the next input. It just does the check and then moves on to the next input. For example, if I'm running a script called "subscript" on 50 files, it'll run the first 20, then spit out "Waiting for a window to free up" 30 times before exiting.

Can anyone tell me why it's not working the way I want it to? There is a piece of Applescript in there, btw. Here is the relevant excerpt from my script:

for input in $inputlist
do
	if [ $windows -lt $maxwindows ]	
	then
	    windows=`cat ${mypwd}Windows.txt`
	    windows=`expr $windows + 1`
	    echo $windows > ${mypwd}Windows.txt
	    echo $var | pbcopy
	    osascript -e 'tell app "Terminal" 
do script "subscript `pbpaste`
end tell'
	    shift
	    sleep .1
	    continue
	else 
	    windows=`cat ${mypwd}Windows.txt`
	    echo $windows
	    echo "Waiting for a window to free up"
	    sleep .4
	    windows=`cat ${mypwd}Windows.txt`
	    continue
	fi
    done
done

How about this (simulated your osascript with random sleep).

Things strange in your script:

  1. shift command does nothing usefull
  2. extra done one end
  3. should refresh windows at top of loop to trap finished sub-processes
inputlist=$(seq 1 50)
mypwd=./
maxwindows=20
windows=0
echo 0 > ${mypwd}Windows.txt
for input in $inputlist
do
    windows=`cat ${mypwd}Windows.txt`
    [ $windows -ge $maxwindows ]  && echo "Waiting for a window to free up"
    while [ $windows -ge $maxwindows ]
    do
        sleep .8
        windows=`cat ${mypwd}Windows.txt`
    done
 
    windows=`cat ${mypwd}Windows.txt`
    windows=`expr $windows + 1`
    echo $windows > ${mypwd}Windows.txt
    echo "Starting window $windows"
    (   sleep $(( 9 + (  RANDOM / 8192 ) ))
        lwin=`cat ${mypwd}Windows.txt`
        lwin=`expr $lwin - 1`
        echo $lwin > ${mypwd}Windows.txt
    ) &
    sleep .1
done

Thanks, Chubler. That works perfectly. I'm new to shell scripting (started grad school a year ago and have been teaching myself shell scripting to do brain image analysis). About your notes:

1) I got this script working so that it took the inputs in the Terminal window (you'd have to type in "Parallel 1 2 3 4 5..." into Terminal), but it only worked with the first shift command, for some reason. The second one was so that I didn't have thousands of "Waiting to open window" notices, but you solved that problem.

2) Yeah, that "done" was from a for loop I have embedded earlier in the script.

3) That makes perfect sense.

One thing I don't understand about your changes, though, is why [ $windows -ge $maxwindows ] is in there twice. Does the first one need to be there for the while loop to run?

Coming up with the script I had so far had been a great learning experience, but I learned more from understanding the changes you made than I have in weeks of reading message boards and guides. Thanks a million.

The first one has nothing to do with the loop, it's a statement all by itself.

[ $windows -ge $maxwindows ]  && echo "Waiting for a window to free up"

If $windows is greater or equal to $maxwindows, it prints the message. && is short form for 'if the first succeeds, run the second', very useful for short things where you don't need to bother with an entire code block.

Try these statements for instance:

true && echo "This will always print"
false && echo "But this never will"

true || echo "This shouldn't print"
false || echo "But this should"
1 Like

Just fooled around with those statements. Interesting. It sounds almost like an "if... then" test.