Skrypt do ssh i uruchom polecenie nie działa


10

Poniżej znajduje się skrypt.

Chciałem zalogować się do kilku serwerów i sprawdzić wersję jądra.

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

Oczekiwałbym produkcji, która idzie jak ...

server1_hostname
kernel_version
server2_hostname
kernel_version

i tak dalej..

Uruchomiłem ten skrypt z około 80 serwerami w server.txt

A wynik, który uzyskałem, był jak .....

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.

Tutaj otrzymałem dane wyjściowe tylko dla 1 hosta, który również jest xxxxdev01dostarczany z banerem ssh i innym ostrzeżeniem.

Potrzebuję danych wyjściowych wszystkich innych hostów i bez bannera ssh. Co się tutaj dzieje?


Co się stanie, jeśli użyjesz jednego z serwerów ręcznie i uruchomisz sshpass -p password root@server histname?
terdon

1
Użyj ssh -t -t root@..., aby wymusić pseudoterminal.
garethTheRed

Odpowiedzi:


11

Nie mogę ci powiedzieć, dlaczego nie otrzymujesz oczekiwanych danych wyjściowych z poleceń hostnamei uname, ale mogę pomóc z obcym tekstem.

Linie „pseudo-terminalu” są drukowane, sshponieważ próbuje domyślnie przydzielić TTY, gdy w wierszu poleceń nie podano żadnego polecenia do wykonania. Możesz uniknąć tej wiadomości, dodając „-T” do polecenia ssh:

sshpass -p password ssh -T root@$line

Linia „Ostrzeżenie: brak dostępu do tty” pochodzi z powłoki w systemie zdalnym. cshi tcshwydrukuje tę wiadomość w określonych okolicznościach. Możliwe, że jest on wyzwalany przez coś w tym .cshrclub podobnym pliku w systemie zdalnym, próbując uzyskać dostęp do funkcji wymagającej TTY.


4

Użyj następującego kodu,

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

Właśnie tego próbowałem najpierw. Ale nie daje mi oczekiwanej wydajności.
Będąc Gokul

1

Jeśli Twoje hosty są przechowywane w następujący sposób server.txt

host1.tld
host2.tld
....

Możesz

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

1

Stdin nie jest dostępny dla twoich zdalnych poleceń. Możesz użyć flagi „-s” bash do odczytu poleceń ze standardowego wejścia:

Z podręcznika 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.

To powinno zrobić, co chcesz:

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

Zobacz także: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine


1

Działa to dla mnie świetnie:

 # 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

Uwaga: użyj -t -tzamiast, -Taby uniknąć błędu

Pseudo-terminal nie zostanie przydzielony, ponieważ stdin nie jest terminalem


1
Powinieneś przeczytać o formatowaniu. Twoja odpowiedź może być doskonała, ale teraz jest prawie nieczytelna.
roaima

0

Wydaje mi się, że ssh w międzyczasie zjadam resztę na standardowe wyjście. szczegółowe informacje można znaleźć w FAQ Bash 89 . W przypadku FileDescriptor następujące kody powinny działać zgodnie z oczekiwaniami.

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

alternatywnym sposobem jest użycie / dev / null dla ssh. FileDescriptor można zignorować. `podczas odczytu linii; wykonaj sshpass -p hasło ssh root @ $ line </ dev / null << EOF .... zrobione <server.txt`
Leon Wang
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.