Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running programs in parallel using xargs

I currently have the current script.

#!/bin/bash # script.sh  for i in {0..99}; do    script-to-run.sh input/ output/ $i done 

I wish to run it in parallel using xargs. I have tried

script.sh | xargs -P8 

But doing the above only executed once at the time. No luck with -n8 as well. Adding & at the end of the line to be executed in the script for loop would try to run the script 99 times at once. How do I execute the loop only 8 at the time, up to 100 total.

like image 849
Olivier Avatar asked Feb 06 '15 03:02

Olivier


People also ask

How do I run multiple commands in xargs?

To run multiple commands with xargs , use the -I option. It works by defining a replace-str after the -I option and all occurrences of the replace-str are replaced with the argument passed to xargs.

What is the point of xargs?

Xargs is a great command that reads streams of data from standard input, then generates and executes command lines; meaning it can take output of a command and passes it as argument of another command. If no command is specified, xargs executes echo by default.

Can we use xargs and standard input?

xargs is a Unix command which can be used to build and execute commands from standard input.

How do you pass arguments to xargs?

The -c flag to sh only accepts one argument while xargs is splitting the arguments on whitespace - that's why the double quoting works (one level to make it a single word for the shell, one for xargs).


1 Answers

From the xargs man page:

This manual page documents the GNU version of xargs. xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is /bin/echo) one or more times with any initial- arguments followed by items read from standard input. Blank lines on the standard input are ignored.

Which means that for your example xargs is waiting and collecting all of the output from your script and then running echo <that output>. Not exactly all that useful nor what you wanted.

The -n argument is how many items from the input to use with each command that gets run (nothing, by itself, about parallelism here).

To do what you want with xargs you would need to do something more like this (untested):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/ 

Which breaks down like this.

  • printf %s\\n {0..99} - Print one number per-line from 0 to 99.
  • Run xargs
    • taking at most one argument per run command line
    • and run up to eight processes at a time
like image 152
Etan Reisner Avatar answered Sep 22 '22 23:09

Etan Reisner