Script para ssh e executar um comando não funciona


10

Abaixo está o script.

Eu queria entrar em vários servidores e verificar a versão do 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

Eu esperaria uma saída que é como ..

server1_hostname
kernel_version
server2_hostname
kernel_version

e assim por diante..

Eu executei esse script com cerca de 80 servidores no server.txt

E a saída que obtive foi 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.

Aqui obtive saída para apenas 1 host, o que é xxxxdev01e também vem com o banner ssh e outros avisos.

Preciso de saída de todos os outros hosts e sem banner ssh .. O que está errado aqui?


O que acontece se você usar um dos servidores manualmente e executar sshpass -p password root@server histname?
terdon

1
Use ssh -t -t root@... para forçar um pseudo-terminal.
garethTheRed

Respostas:


11

Não sei dizer por que você não está obtendo a saída esperada dos comandos hostnamee uname, mas posso ajudar com o texto estranho.

As linhas "Pseudo-terminal" estão sendo impressas sshporque tentam alocar um TTY por padrão quando nenhum comando a ser executado foi fornecido na linha de comando. Você pode evitar essa mensagem adicionando "-T" ao comando ssh:

sshpass -p password ssh -T root@$line

A linha "Warning: no access to tty" vem do shell no sistema remoto. cshe tcshimprimirá essa mensagem sob certas circunstâncias. É possível que tenha sido acionado por algo no .cshrcarquivo ou similar no sistema remoto, tentando acessar algum recurso que requer um TTY.


4

Use o seguinte 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

Isto é o que eu tentei primeiro. Mas isso não me dá a saída esperada.
Sendo Gokul

1

Se seus hosts estiverem armazenados da seguinte maneira server.txt

host1.tld
host2.tld
....

Você pode

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

1

O stdin não está acessível aos seus comandos remotos. O que você pode fazer é usar o sinalizador "-s" do bash para ler comandos do stdin:

No manual do 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.

Portanto, isso deve fazer o que você deseja:

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

Consulte também: /programming/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine


1

Isso funciona muito bem para mim:

 # 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

note que use em -t -tvez de -Tpara evitar o erro

O pseudo-terminal não será alocado porque stdin não é um terminal


1
Você deve ler sobre formatação. Sua resposta pode ser excelente, mas agora é praticamente ilegível.
roaima

0

Eu acho que o ssh enquanto come o resto para stdin. você pode consultar a FAQ do Bash 89 para obter detalhes. Com um FileDescriptor, os seguintes códigos devem funcionar como sua expectativa.

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

a maneira alternativa é usar / dev / null para ssh. FileDescriptor pode ser ignorado. `enquanto lê a linha; do sshpass -p senha ssh root @ $ line </ dev / null << EOF .... feito <server.txt` #
Leon Wang Leon
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.