Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get multiple bash background scripts, spawned from one initial startup script to log on the correct line of the terminal?

Tags:

linux

bash

shell

I have a bash script something like this:

# one.sh, two.sh and three.sh do not depend on anything,
# and can run simultaneously in any order,
# and the execution time for each is random

# four.sh can only run once three.sh has finished

one.sh &
ONE=$!

two.sh &
TWO=$!

three.sh &
THREE=$!

wait $THREE
four.sh

where one.sh, two.sh and three.sh look something like this:

echo -n "doing stuff..."
#some command or set of commands
if [ $? ]
then
    echo $RESULT_PASS
else
    echo $RESULT_FAIL
fi

the output i'm getting is something like this:

doing stuff1...done
doing stuff2...
doing stuff3...
doing stuff4...done
7263
doing stuff5...done
doing stuff6...9823
doing stuff7...done 
9283

because some tasks in one script are not complete before tasks in another script have started.

the output i'm looking for is something like this:

doing stuff1...done
doing stuff2...done
doing stuff3...8373
doing stuff4...done
doing stuff5...1234
doing stuff6...fail
doing stuff7...done

I would be grateful for some guidance.

Thanks!

like image 429
Shaarpe Avatar asked Jan 26 '23 20:01

Shaarpe


1 Answers

I would use GNU Parallel to run scripts in parallel. It is very simple, intuitive and flexible. So, to run three scripts in parallel and keep the output in order and wait till all three have finished:

parallel -k ::: ./one.sh ./two.sh ./three.sh

Sample Output

doing stuff1...pass
doing stuff2...pass
doing stuff3...pass

Search for examples on Stack Overflow by typing [gnu-parallel] in the search box - include the square brackets. You can run as many as you want in parallel, tag the output lines, round-robin large files across multiple processes, remote login to other machines to spread processes across a network, halt all other scripts if one fails, or if 10% fail, or if any pass...


Or you can ask GNU Parallel to tag each line with the name of the script:

parallel -k --tag ::: ./one.sh ./two.sh ./three.sh
./one.sh    doing stuff1...pass
./two.sh    doing stuff2...pass
./three.sh  doing stuff3...pass
like image 197
Mark Setchell Avatar answered Feb 05 '23 18:02

Mark Setchell