I have list of shell commands that I'd like to call. Up to four processes shall run at the same time.
My basic idea would be to send the commands to the shell until 4 commands are active. The script then constantly checks the process count of all processes by looking for a common string e.g. "nohup scrapy crawl urlMonitor".
As soon as the process count drops below 4, the next command is sent to the shell until all command have finished.
Is there a way to do this with a shell script? I suppose it would involve some kind of endless loop, and break condition as well as method to check for the active processes. Unfortunately I am not that good in shell scripting, so perhaps someone can guide me into the right direction?
nohup scrapy crawl urlMonitor -a slice=0 &
nohup scrapy crawl urlMonitor -a slice=1 &
nohup scrapy crawl urlMonitor -a slice=2 &
nohup scrapy crawl urlMonitor -a slice=3 &
nohup scrapy crawl urlMonitor -a slice=4 &
nohup scrapy crawl urlMonitor -a slice=5 &
nohup scrapy crawl urlMonitor -a slice=6 &
nohup scrapy crawl urlMonitor -a slice=7 &
nohup scrapy crawl urlMonitor -a slice=8 &
nohup scrapy crawl urlMonitor -a slice=9 &
nohup scrapy crawl urlMonitor -a slice=10 &
nohup scrapy crawl urlMonitor -a slice=11 &
nohup scrapy crawl urlMonitor -a slice=12 &
nohup scrapy crawl urlMonitor -a slice=13 &
nohup scrapy crawl urlMonitor -a slice=14 &
nohup scrapy crawl urlMonitor -a slice=15 &
nohup scrapy crawl urlMonitor -a slice=16 &
nohup scrapy crawl urlMonitor -a slice=17 &
nohup scrapy crawl urlMonitor -a slice=18 &
nohup scrapy crawl urlMonitor -a slice=19 &
nohup scrapy crawl urlMonitor -a slice=20 &
nohup scrapy crawl urlMonitor -a slice=21 &
nohup scrapy crawl urlMonitor -a slice=22 &
nohup scrapy crawl urlMonitor -a slice=23 &
nohup scrapy crawl urlMonitor -a slice=24 &
nohup scrapy crawl urlMonitor -a slice=25 &
nohup scrapy crawl urlMonitor -a slice=26 &
nohup scrapy crawl urlMonitor -a slice=27 &
nohup scrapy crawl urlMonitor -a slice=28 &
nohup scrapy crawl urlMonitor -a slice=29 &
nohup scrapy crawl urlMonitor -a slice=30 &
nohup scrapy crawl urlMonitor -a slice=31 &
nohup scrapy crawl urlMonitor -a slice=32 &
nohup scrapy crawl urlMonitor -a slice=33 &
nohup scrapy crawl urlMonitor -a slice=34 &
nohup scrapy crawl urlMonitor -a slice=35 &
nohup scrapy crawl urlMonitor -a slice=36 &
nohup scrapy crawl urlMonitor -a slice=37 &
nohup scrapy crawl urlMonitor -a slice=38 &
Here's a general method that will always ensure that there are less than 4 jobs before launching any other jobs (yet, there may be more than 4 jobs simultaneously if a line launches several jobs at once):
Use this script with your file as first argument.
How does it work? for each line
line
read, we first ensure that there are less thanmax_nb_jobs
running by counting the number of running jobs (obtained fromjobs -pr
). If there are more thanmax_nb_jobs
, we wait for the next job to terminate (wait -n
), and count again the number of running jobs. If there are less thanmax_nb_jobs
running, weeval
the lineline
.Update
Here's a similar script that doesn't use
wait -n
. It seems to do the job all right (tested on Debian with Bash 4.2):You could do this easily with GNU parallel or even just xargs. To wit:
The
while
loop will run forever; if there's an actual hard limit you know of you can just do afor
loop like:Also, the
sleep 1
is helpful because it lets the shell handle signals more effectively.Try doing this :
help wait
:If you want 4 at a time continuously running, try something like:
This is a variation on sputnick's answer that keeps up to
max_procs
running at the same time. As soon as one finishes, it kicks off the next one. Thewait -n
command waits for the next process to finish instead of waiting for all of them to finish.