42

In Linux, you can use xargs -d, to quickly run the hostname command against four different servers with sequential names as follows:

echo -n 1,2,3,4 |xargs -d, -I{} ssh root@www{}.example.com hostname

It looks like the OSX xargs command does not support the delimiter parameter. Can you achieve the same result with a differently formatted echo, or through some other command-line utility?

Chase Seibert
  • 541
  • 1
  • 5
  • 7

5 Answers5

70

Alternatively, you can always install GNU xargs through Homebrew and the GNU findutils package.

Install Homebrew:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Follow the instructions. Then install findutils:

brew install findutils

This will give you GNU xargs as gxargs, and you can use the syntax you're accustomed to from GNU/Linux. The same goes for other basic commands found in the findutils package such as gfind or glocate or gupdatedb, which have different BSD counterparts on OS X.

slhck
  • 223,558
  • 70
  • 607
  • 592
20

How about:

echo {1..4} | xargs -n1 -I{} ssh root@www{}.example.com hostname

From man xargs:

-n number
Set the maximum number of arguments taken from standard input for each invocation of utility.
slhck
  • 223,558
  • 70
  • 607
  • 592
Gordon Davisson
  • 34,084
  • 5
  • 66
  • 70
  • 2
    If the values can contain spaces, linefeeds, or tabs, you could use something like `printf 'a\0a' | xargs -0 -n1 echo`. – Lri Oct 18 '12 at 07:20
  • this doesn't work with gnu xargs, ie, all of debian `https://asciinema.org/a/jfqOwiRpH6IFGZDrPTo0qQTNf`. Shame! Shame! ;) – christian elsee May 17 '22 at 20:57
  • as a bonus, you can also add `-P n` which will parallelize it. Since it's all IO, this can be helpful. So, `-P 4` – Christian Bongiorno Jun 23 '23 at 16:11
4

You can also use tr in OSX to convert the commas to new lines and use xargs to enumerate through each item as follows:

echo -n 1,2,3,4 | tr -s ',' '\n' | xargs -I{} ssh root@www{}.example.com hostname
John
  • 191
  • 6
2

If you want it run in parallel, use GNU Parallel:

parallel ssh root@www{}.example.com hostname ::: {1..4}
Ole Tange
  • 4,529
  • 2
  • 34
  • 51
1

with printf

$ printf '%s\n' 1 2 3 4 | xargs -I{} echo ssh root@www{}.example.com hostname
ssh root@www1.example.com hostname
ssh root@www2.example.com hostname
ssh root@www3.example.com hostname
ssh root@www4.example.com hostname