Ein Skript zum ssh und Ausführen eines Befehls funktioniert nicht

10

Unten ist das Skript.

Ich wollte mehrere Server anmelden und nach der Kernelversion suchen.

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done

Ich würde eine Ausgabe erwarten, die wie folgt geht.

server1_hostname
kernel_version
server2_hostname
kernel_version

und so weiter..

Ich habe dieses Skript mit ungefähr 80 Servern in server.txt ausgeführt

Und die Ausgabe, die ich bekam, war wie .....

Pseudo-terminal will not be allocated because stdin is not a terminal. 
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

========================================================================
================================ WARNING ===============================
========================================================================
This system is solely for the use of authorized personnel. Individuals
using this system are subject to having some or all of their activities
monitored and recorded. Anyone using this system expressly consents to
such monitoring and is advised that any unauthorized or improper use of
this system may result in disciplinary action up to and including
termination of employment. Violators may also be subject to civil and/or
criminal penalties.
========================================================================

Warning: no access to tty (Bad file descriptor).
Thus no job control in this shell.
xxxxdev01
2.6.32-431.23.3.el6.x86_64
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.
Pseudo-terminal will not be allocated because stdin is not a terminal.

Hier habe ich nur für 1 Host ausgegeben, xxxxdev01und das kommt auch mit dem SSH-Banner und anderen Warnungen.

Ich brauche die Ausgabe aller anderen Hosts und ohne SSH-Banner. Was läuft hier falsch?

Gokul sein
quelle
Was passiert, wenn Sie einen der Server manuell verwenden und ausführen sshpass -p password root@server histname?
Terdon
1
Verwenden Sie ssh -t -t root@..., um ein Pseudo-Terminal zu erzwingen.
GarethTheRed

Antworten:

11

Ich kann Ihnen nicht sagen, warum Sie nicht die erwartete Ausgabe von den Befehlen hostnameund erhalten uname, aber ich kann Ihnen mit dem fremden Text helfen.

Die "Pseudo-Terminal" -Zeilen werden gedruckt, sshweil standardmäßig versucht wird, eine TTY zuzuweisen, wenn in der Befehlszeile kein auszuführender Befehl angegeben wurde. Sie können diese Meldung vermeiden, indem Sie dem Befehl ssh "-T" hinzufügen:

sshpass -p password ssh -T root@$line

Die Zeile "Warnung: Kein Zugriff auf tty" kommt von der Shell auf dem Remote-System. cshund tcshdruckt diese Nachricht unter bestimmten Umständen. Es ist möglich, dass es durch etwas in der .cshrcoder einer ähnlichen Datei auf dem Remote-System ausgelöst wird , das versucht, auf eine Funktion zuzugreifen, für die ein TTY erforderlich ist.

Kenster
quelle
4

Verwenden Sie den folgenden Code:

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
  sshpass -p password ssh root@$line 'hostname;uname -r'
done
msnfreaky
quelle
Das habe ich zuerst versucht. Aber es gibt mir nicht die erwartete Ausgabe.
Als Gokul
1

Wenn Ihre Hosts wie folgt gespeichert sind server.txt

host1.tld
host2.tld
....

Du kannst

mapfile -t myhosts < server.txt; for host in "${myhosts[@]}"; do ssh username@"$host" 'hostname;uname -r'; done
Valentin Bajrami
quelle
1

Das stdin ist für Ihre Remote-Befehle nicht zugänglich. Was Sie tun können, ist das "-s" -Flag von bash zu verwenden, um Befehle aus dem stdin zu lesen:

Aus dem Bash-Handbuch:

-s        If the -s option is present, or if no arguments remain after
          option processing, then commands are read from the standard 
          input.  This option allows the positional parameters to be set
          when  invoking  an  interactive shell.

Das sollte also tun, was Sie wollen:

#!/bin/bash
#input server names line by line in server.txt
cat server.txt | while read line
do
    sshpass -p password ssh root@$line bash -s << EOF
hostname
uname -r
EOF
done

Siehe auch: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine

Nimai
quelle
1

Das funktioniert gut für mich:

 # cat hostsname.txt 
operation01  172.20.68.37 5fDviDEwew
ngx-gw01     172.20.68.36 FiPp2UpRyu
gateway01    172.20.68.35 KeMbe57zzb
vehicle01    172.20.68.34 FElJ3ArM0m

# cat hostsname.txt | while read hostname ipaddr passwd; do sshpass -p $passwd /usr/bin/ssh-copy-id $ipaddr;done

Beachten Sie, dass Sie -t -tanstelle von verwenden -T, um den Fehler zu vermeiden

Pseudo-Terminal wird nicht zugewiesen, da stdin kein Terminal ist

Tapferer Jiang
quelle
1
Sie sollten sich über die Formatierung informieren. Ihre Antwort mag ausgezeichnet sein, aber gerade jetzt ist sie ziemlich unlesbar.
Roaima
0

Ich denke, die SSH in der Zwischenzeit frisst den Rest auf, um zu stdin. Weitere Informationen finden Sie in den Bash- FAQ 89 . Mit einem FileDescriptor sollten die folgenden Codes Ihren Erwartungen entsprechen.

while read line <& 7
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done 7< server.txt
Leon Wang
quelle
Die alternative Möglichkeit besteht darin, / dev / null für ssh zu verwenden. FileDescriptor kann ignoriert werden. `während Zeile lesen; sshpass -p Passwort ssh root @ $ line </ dev / null << EOF .... erledigt <server.txt`
Leon Wang