0

I'm trying to write a bash script using PSSH which sends the same command but different arguments depending on the host. The host name and arguments will be pulled from a different file 'list.txt'.

An example of a 'list.txt' file would look like this:

10.0.0.1;'hello';'world'
10.0.0.2;'goodbye';'everyone'
10.0.0.3;'thank';'you!'

An example of what I currently have (but unfortunately isn't working) is shown below:

#!/bin/bash

# grab the list items and make them into a variable to be able to parse
actionList=$(</root/scripts/list.txt)

# parse out host name for pssh
host_name="$( cut -d ';' -sf 1 <<< "$actionList" )";

# parse out the first argument 
argument1="$( cut -d ';' -sf 2 <<< "$actionList" )";

# parse out the second argument
argument2="$( cut -d ';' -sf 3 <<< "$actionList" )";

# pssh command that creates a new file on each server with their respective argument1 and argument2 
pssh -i -AH $host_name -t 300 -O StrictHostKeyChecking=no "$(argument1) ' and ' $(argument2) >> arg1_and_arg2.txt" 

I'm pretty sure cutting the $actionList variable is not giving me what I want, but what I'm really stuck on is whether that pssh command will run correctly for every item in 'list.txt' after I've parsed out the correct strings from $actionList.

Is there a way to make same command, changing arguments from file work with PSSH? Is there a better program to do this with? If so how? Any help is appreciated.

Thanks!

P.S. If I formatted or did anything wrong with this post, I apologize. StackOverflow is usually my last resort so I don't use it often. Again, thanks for any help/advice!

  • I don't think `pssh` can do what you want; it is intended to run the *same* command (arguments included) on different hosts. – chepner Feb 05 '19 at 18:50
  • Note that expanding a variable creates *literal* quotes (ones that are data), not *syntactic* ones (quotes that are parsed as syntax by bash). Thus, you almost certainly want to leave the `'`s out of your file. – Charles Duffy Feb 05 '19 at 19:00
  • @chepner I was afraid of that answer.. Happen to know of any other utilities/programs that can help accomplish this? – Francisco Tapia Feb 05 '19 at 20:59
  • @CharlesDuffy thanks for the info! Will change that from now on! – Francisco Tapia Feb 05 '19 at 21:00

1 Answers1

1

I think you are better off simply using a loop that runs ssh for each line of the input file.

while IFS=";" read host arg1 arg2; do
    echo "$arg1 and $arg2" | ssh "$host" "cat > arg1_and_arg2.txt" &
done < list.txt
chepner
  • 497,756
  • 71
  • 530
  • 681
  • I do already have a way to do this sequentially, but would like to be able to run this command in parallel to be time efficient. – Francisco Tapia Feb 05 '19 at 20:58
  • @FranciscoTapia, see the `&` causing the pipeline running `ssh` to be started in the background. On account of that, this *does* run code in parallel. (The most obvious risk here is that it may be *too* parallel, if you have a longer list of hosts than you can afford to start concurrent processes for, but that's something a little restructuring with `xargs -P` will fix). – Charles Duffy Feb 05 '19 at 21:06
  • @CharlesDuffy Wow, totally missed the '&' ! And yes, I may need to run this command on 400+ hosts so I would need to limit the amount of concurrent processes. I'll most definitely look into this solution more and will update this question with my solution. Thanks again for your help! – Francisco Tapia Feb 06 '19 at 03:29
  • Honestly, 400 processes isn't *that* many, especially since the amount of work each does locally is minimal. Each process will spend nearly all its time simply sleeping until the remote process completes. – chepner Feb 06 '19 at 04:12
  • @chepner this worked for what I needed! Thanks for the help again! Will have to look into the ' xargs ' option Charles pointed out. For now everything is good to go! – Francisco Tapia Feb 06 '19 at 18:47