Permission denied when trying to run a script that uses 'sshpass'

The idea is to make this script run without needing to type any passwords of the hosts (written down in the Hosts.txt file). Right now, when I'm running this, I get a Permission denied, please try again. as an answer.

#!/bin/bash

[[ -z "${1}" ]] && OUT_FILE="WhereTheAnswearIsGoing.txt" || OUT_FILE="$1"
[[ -z "${2}" ]] && IN_FILE="Hosts.txt" || IN_FILE="$2"

while IFS= read -r host; do
        indication="$(sshpass -pfootbar ssh -p 2222 -o StrictHostKeyChecking=no -n "$host" 'who -b' | awk '{print $(NF-1)" "$NF}')"
        printf '%-14s %s\n' "$indication" "$host" >> "$OUT_FILE"
done < "$IN_FILE"

Sorry if this question is unclear but I don't know much about things like these.


It looks the message Permission denied, please try again. is generated by the SSH client. The password should be quoted to escape the special meaning of characters as $, !, etc. (ref):

sshpass -p 'footbar' ...

Or you can use a file where the password to be stored (source):

sshpass -f "/path/to/passwordfile" ...

enter image description here


However, I remember, this is a script from my previous answer where I mentioned that: "Note here is assumed there is ~/.ssh/config file and additional parameters as -p 2222 are not needed (reference)." What I meant was:

The better solution is to (1) setup Key based SSH authentication, (2) create ~/.ssh/config file and (3) modify the script to work with this setup.

1. Setup Key based SSH authentication (source).

  • Generating RSA Keys and don't enter passphrase:

    mkdir ~/.ssh
    chmod 700 ~/.ssh
    ssh-keygen -t rsa -b 4096
    chmod 600 ~/.ssh/id_rsa
    
  • Transfer Client Key to each Host (please note the quote marks):

    ssh-copy-id "<username>@<host> -p <port_nr>"
    
  • Now you should be able to connect to the server(s) without password:

    ssh <username>@<host> -p <port_nr>
    
  • Once this works, you could disable the password authentication (that is less secure method) by editing the file /etc/ssh/sshd_config of each host machine in this way:

    #PasswordAuthentication yes
    PasswordAuthentication no
    

2. Create ~/.ssh/config file. (Read also: How do I add multiple machines with the same configuration to ~/.ssh/config?)

  • The content of the file ~/.ssh/config could look as this (host-i is object of your choice):

    Host host-1
        HostName <domain-or-IP-address>
        IdentityFile ~/.ssh/id_rsa
        User <username>
        Port 2222
        # other parameters...
    
    Host host-2
        HostName <domain-or-IP-address>
        IdentityFile ~/.ssh/id_rsa
        User <username>
        Port 2222
        # other parameters...
    
    Host host-3...
    
  • Change the file permissions:

    chmod 600 ~/.ssh/config
    
  • Now you should be able to connect to each of these hosts by a command as:

    ssh host-1
    

3.A. You can keep using the above scrip with a little modification:

#!/bin/bash

[[ -z "${1}" ]] && OUT_FILE="WhereTheAnswearIsGoing.txt" || OUT_FILE="$1"
[[ -z "${2}" ]] && IN_FILE="Hosts.txt" || IN_FILE="$2"

while IFS= read -r host; do
        indication="$(ssh -n "$host" 'who -b' | awk '{print $(NF-1)" "$NF}')"
        printf '%-14s %s\n' "$indication" "$host" >> "$OUT_FILE"
done < "$IN_FILE"

In this case the Hosts.txt file should be:

host-1
host-2
host-3

3.B. Or you can modify the script in more general way:

#!/bin/bash

# Collect the user's input, and if it`s empty set the default values
[[ -z "${1}" ]] && OUT_FILE="WhereTheAnswearIsGoing.txt" || OUT_FILE="$1"
# Provide the list of the hosts as an array
HOSTS=("host-1" "host-2" "host-3")

for host in "${HOSTS[@]}"; do
    indication="$(ssh -n "$host" 'who -b' | awk '{print $(NF-1)" "$NF}')"
    printf '%-14s %s\n' "$host" "$indication" >> "$OUT_FILE"
done