I have this text:

node1: connect command: ssh user@ password: qcipunbnctza
node2: connect command: ssh user@ password: ejrpnnwsczpa
node3: connect command: ssh user@ password: pkrpxmyxnxuu

I need to save ip addresses and passwords to variables then pass it to script. How can I do in in efficent way? My script is:

declare -a IPS=($1 $2 $3)
CONFIG_FILE=inventory/sks-cluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
echo $4 > host1.txt
echo $5 > host2.txt
echo $6 > host3.txt
ssh-keyscan $1
ssh-keyscan $2
ssh-keyscan $3
sshpass -f host1.txt ssh-copy-id user@$1
sshpass -f host2.txt ssh-copy-id user@$2
sshpass -f host3.txt ssh-copy-id user@$3
  • Unless the python3 contrib/inventory_builder/inventory.py has to run on all IP's at the same time it would be neater and simpler to loop over the lines instead.
    – Nifle
    Mar 16 at 22:24
  • Even if simultaneous execution was required, it would still be simpler and neater to use a loop. just run each python3 instance in the background with &, possibly redirecting stdout & stderr to either /dev/null or to a separate log file for each host.
    – cas
    Mar 17 at 2:42

2 Answers 2


Try something like this:


export SSHPASS
awk -F'[@ ]' '{print $5, $6, $8}' hostlist.txt |
  while read -r username host SSHPASS ; do
    echo ssh-keyscan "$host"
    echo sshpass -e ssh-copy-id "$username@$host"

This uses an awk one-liner to extract the username, the hostname/IP address, and the password of each line from a file called hostlist.txt, with the output being piped into a while loop.

The while loop processes the output from awk and uses it with ssh-keyscan and sshpass (using the -e option instead of -f, so that it uses the environment variable $SSHPASS instead of a file) for each input line.

SSHPASS is exported to ensure that it is available in the environment when sshpass is run.

NOTE: I've used echo before ssh-keyscan and sshpass to make this a dry-run (and because testing it is faster if my system doesn't have to waste time trying to connect to those IP addresses with ssh-keyscan and ssh-pass+ssh-copy-id). Remove the echo from both lines when you're sure it's going to work as intended.

  • Til: -F'[@ ]' , how very useful
    – Nifle
    Mar 17 at 8:57
  • 1
    @Nifle @|[[:blank:]]+ works too. probably works better in most cases because it allows one or more spaces or tabs as the field separator (same as the awk default) rather than just a single space. awk allows any regex (ERE syntax) for FS.
    – cas
    Mar 17 at 11:06

Here is a very naive way to do it.

If your script is called yourscript.sh and the data is in a file called nodes.txt

yourscript.sh  $(cat nodes.txt |  tr '@' ' ' | cut -f6 -d' '; cut -f7 -d' ' nodes.txt)
  • can you explain how works cut in this case? First we truncate '@', then pass all colums to cut. And how it works after that?
    – VladF
    Mar 17 at 7:44
  • @VladF 'tr' replaces the @with a space, cut can then select colum 6 using space as a field separator, this prinys the ip-numbers ; starts a new command where we extract the password using cut The $( ..... ) runs the code inside it and returns whatever is printed to stdout on one line.
    – Nifle
    Mar 17 at 8:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .