0

Purpose

This script is meant to copy one's public ssh identity file to many hosts that are listed in a file

Problem

The script is not properly reading IP's from the file. I believe this is because it is not reading the lines of the file. When I echo out the line (IP) it is reading, it is blank.

Code

#!/bin/bash
usage="Usage: $(basename "$0") [-h|-u|-i|-p|-f] -- Copys your identity key to a list of remote hosts
where:
-h Show this help text
-u Username of ssh user
-i Location of identity file (Default: /home/$USER/.ssh/id_rsa.pub)
-p Password (not secure)
-f Location of hosts file (Default: ./inventory)"

# Default location for files
CURR_DIR="$(cd "$(dirname "$0")" && pwd)"
HOSTS_FILE=${CURR_DIR}/inventory
IDENT_FILE=/home/$USER/.ssh/id_rsa.pub

# required_flag=false

while getopts 'hu:i:p:f:' option; do
  case $option in
    # Help
    h) echo "$usage"; exit;;
    # Hosts file
    f) HOSTS_FILE=$OPTARG;;
    # Password
    p) PASSWORD=$OPTARG;;
    # Indentity file
    i) IDENT_FILE=$OPTARG; echo "$IDENT_FILE";;
    # Username
    u) USERNAME=$OPTARG;;
    # Missing args
    :) printf "Option -%s\n requires an argument." "-$OPTARG" >&2; echo "$usage" >&2; exit 1;;
    # Illegal option
    \?) printf "Illegal option: -%s\n" "$OPTARG" >&2; echo "$usage" >&2; exit 1;;
  esac
done

shift "$((OPTIND-1))"
#  Decrements the argument pointer so it points to next argument.
#  $1 now references the first non-option item supplied on the command-line
#+ if one exists.

# if ! $required_flag && [[ -d $1 ]]
# then
#     echo "You must specify a hosts file. -h for more help." >&2
#     exit 1
# fi

while IFS= read -r line;
do
     echo "Current IP: " "$IP"
     echo "Current Username: " "$USERNAME"
     echo "Current Identity: " "$IDENT_FILE"
     echo "Current Hosts: " "$HOSTS_FILE"
     echo "Current Password: " "$PASSWORD"
     sshpass -p "$PASSWORD" ssh-copy-id -i "$IDENT_FILE" "$USERNAME"@"$IP"
done < $HOSTS_FILE

Output

$ ./autocopyid -u user -p password
Current IP:  
Current Username:  user
Current Identity:  /home/user/.ssh/id_rsa.pub
Current Hosts:  /home/user/inventory
Current Password:  password
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: ERROR: ssh: Could not resolve hostname : Name or service not known
akjones
  • 88
  • 5
  • Welcome to Stack Overflow. You've done a pretty good job of creating an MCVE ([MCVE]), except for one key piece — the input data. I see nowhere in the code where you actually assign to `IP` so it isn't all that surprosing that it is empty. Did you need to do something with the value in `line` after the `read` to set `IP`? Should you be reading `read -r IP junk` or something similar? Did you try debugging with `bash -x ./autocopyid -u user -p password`? Did it show a magical assignment to `IP`? – Jonathan Leffler Apr 12 '17 at 01:18

1 Answers1

1

You are not using the variable line for anything. Assuming $HOSTS_FILE points to a file that contains one IP address per line, you now have the IP address in variable line instead of IP in your loop. But since you use the variable name IP in the body of the loop, you should use that in the read statement, too.

So try

while IFS= read -r IP

instead of

while IFS= read -r line
tripleee
  • 175,061
  • 34
  • 275
  • 318
Ville Oikarinen
  • 400
  • 1
  • 11