Lo script per ssh ed eseguire un comando non funziona


10

Di seguito è la sceneggiatura.

Volevo accedere a diversi server e verificare la versione del kernel.

#!/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

Mi aspetterei un output che vada come ..

server1_hostname
kernel_version
server2_hostname
kernel_version

e così via..

Ho eseguito questo script con circa 80 server in server.txt

E l'output che ho ottenuto è stato come .....

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.

Qui ho ottenuto l'output solo per 1 host, che è xxxxdev01e anche quello viene fornito con il banner ssh e altri avvisi.

Ho bisogno dell'output di tutti gli altri host e senza banner SSH. Cosa non va qui?


Cosa succede se si utilizza uno dei server manualmente ed si esegue sshpass -p password root@server histname?
terdon

1
Usa ssh -t -t root@... per forzare uno pseudo-terminale.
garethTheRed,

Risposte:


11

Non posso dirti perché non stai ottenendo l'output previsto dai comandi hostnamee uname, ma posso aiutarti con il testo estraneo.

Le righe "Pseudo-terminale" vengono stampate sshperché tenta di allocare un TTY per impostazione predefinita quando sulla riga di comando non è stato fornito alcun comando da eseguire. Puoi evitare quel messaggio aggiungendo "-T" al comando ssh:

sshpass -p password ssh -T root@$line

La riga "Avvertenza: nessun accesso a tty" proviene dalla shell sul sistema remoto. cshe tcshstamperà quel messaggio in determinate circostanze. È possibile che sia attivato da qualcosa nel .cshrcfile o simile sul sistema remoto, cercando di accedere ad alcune funzionalità che richiedono un TTY.


4

Usa il seguente codice,

#!/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

Questo è quello che ho provato prima. Ma non mi dà l'output previsto.
Essere Gokul il

1

Se i tuoi host sono memorizzati come segue server.txt

host1.tld
host2.tld
....

Puoi

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

1

Lo stdin non è accessibile ai tuoi comandi remoti. Quello che puoi fare è usare il flag "-s" di bash per leggere i comandi dallo stdin:

Dal manuale di bash:

-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.

Quindi questo dovrebbe fare quello che vuoi:

#!/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

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


1

Questo funziona alla grande per me:

 # 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

si noti che utilizzare -t -tinvece di -Tper evitare l'errore

Lo pseudo-terminale non verrà allocato perché stdin non è un terminale


1
Dovresti leggere sulla formattazione. La tua risposta potrebbe essere eccellente, ma in questo momento è praticamente illeggibile.
roaima,

0

Immagino che il ssh nel frattempo mangi il resto a stdin. puoi fare riferimento alle FAQ 89 di Bash per i dettagli. Con un FileDescriptor, i seguenti codici dovrebbero funzionare come previsto.

while read line <& 7
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done 7< server.txt

il modo alternativo è usare / dev / null per ssh. FileDescriptor può essere ignorato. `mentre leggi la riga; fare sshpass -p password ssh root @ $ line </ dev / null << EOF .... done <server.txt`
Leon Wang
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.