La secuencia de comandos para ssh y ejecutar un comando no funciona

10

A continuación se muestra el guión.

Quería iniciar sesión en varios servidores y verificar la versión 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

Esperaría una salida que va como ...

server1_hostname
kernel_version
server2_hostname
kernel_version

y así..

Ejecuté este script con unos 80 servidores en server.txt

Y la salida que obtuve fue como .....

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.

Aquí obtuve salida para solo 1 host, que es xxxxdev01y eso también viene con el banner ssh y otra advertencia.

Necesito la salida de todos los demás hosts y sin banner ssh. ¿Qué está mal aquí?

Ser gokul
fuente
¿Qué sucede si usa uno de los servidores manualmente y lo ejecuta sshpass -p password root@server histname?
terdon
1
Use ssh -t -t root@... para forzar un pseudo-terminal.
garethTheRed

Respuestas:

11

No puedo decirte por qué no obtienes el resultado esperado de los comandos hostnamey uname, pero puedo ayudarte con el texto extraño.

Las líneas "Pseudo-terminal" están siendo impresas por ssh porque intenta asignar un TTY de forma predeterminada cuando no se proporcionó ningún comando para ejecutar en la línea de comando. Puede evitar ese mensaje agregando "-T" al comando ssh:

sshpass -p password ssh -T root@$line

La línea "Advertencia: sin acceso a tty" proviene del shell en el sistema remoto. cshe tcshimprimirá ese mensaje bajo ciertas circunstancias. Es posible que se active por algo en el .cshrcarchivo o similar en el sistema remoto, intentando acceder a alguna función que requiere un TTY.

Kenster
fuente
4

Usa el siguiente código,

#!/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
fuente
Esto es lo que probé primero. Pero no me da el resultado esperado.
Siendo Gokul el
1

Si sus hosts se almacenan de la siguiente manera en server.txt

host1.tld
host2.tld
....

Usted puede

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

El stdin no es accesible para sus comandos remotos. Lo que puede hacer es usar el indicador "-s" de bash para leer los comandos del stdin:

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

Entonces esto debería hacer lo que quieras:

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

Ver también: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine

nimai
fuente
1

Esto funciona muy bien para mí:

 # 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

tenga en cuenta que use en -t -tlugar de -Tpara evitar el error

El pseudo-terminal no se asignará porque stdin no es un terminal

Valiant Jiang
fuente
1
Deberías leer sobre el formateo. Su respuesta puede ser excelente, pero ahora es casi ilegible.
roaima
0

Supongo que el ssh en el tiempo se come el resto para stdin. puede consultar las preguntas frecuentes 89 de Bash para obtener más detalles. Con un FileDescriptor, los siguientes códigos deberían funcionar según sus expectativas.

while read line <& 7
do
sshpass -p password ssh root@$line << EOF
hostname
uname -r
EOF
done 7< server.txt
Leon Wang
fuente
la forma alternativa es usar / dev / null para ssh. FileDescriptor puede ser ignorado. `mientras lee la línea; do sshpass -p contraseña ssh root @ $ line </ dev / null << EOF .... done <server.txt`
Leon Wang