2

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.

3
  • 7
    What exactly is the error output you're receiving? Why is there a dot in your shebang line? Why does your script end with ~? What's the (or a sample) input and what output do you expect? Please edit and clarify. – dessert Dec 14 '17 at 9:56
  • 5
    if you are getting "permission denied", your script probably lacks execute permission (run chmod u+x name_of_script). But indeed it is unclear what the script is trying to do, and hopefully there is a better way of doing it without writing passwords in plain text in any file. – Zanna Dec 14 '17 at 10:02
  • 1
    "but I don't know much about things like these" - If you wrote or changed the script then you better should. Else bad things may happen, as this is security sensitive code. – Murphy Dec 14 '17 at 10:32
8

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
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.