Le script pour ssh et exécuter une commande ne fonctionne pas


10

Voici le script.

Je voulais me connecter à plusieurs serveurs et vérifier la version du noyau.

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

Je m'attendrais à une sortie qui va comme ..

server1_hostname
kernel_version
server2_hostname
kernel_version

etc..

J'ai exécuté ce script avec environ 80 serveurs dans server.txt

Et la sortie que j'ai obtenue était comme .....

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.

Ici, j'ai obtenu la sortie pour seulement 1 hôte, ce qui est xxxxdev01également le cas avec la bannière ssh et d'autres avertissements.

J'ai besoin de la sortie de tous les autres hôtes et sans bannière ssh .. Qu'est-ce qui ne va pas ici?


Que se passe-t-il si vous utilisez l'un des serveurs manuellement et que vous l'exécutez sshpass -p password root@server histname?
terdon

1
Utilisez ssh -t -t root@... pour forcer un pseudo-terminal.
garethTheRed

Réponses:


11

Je ne peux pas vous dire pourquoi vous n'obtenez pas la sortie attendue des commandes hostnameet uname, mais je peux vous aider avec le texte superflu.

Les lignes "Pseudo-terminal" sont imprimées par sshcar il essaie d'allouer un TTY par défaut lorsqu'aucune commande à exécuter n'a été fournie sur la ligne de commande. Vous pouvez éviter ce message en ajoutant "-T" à la commande ssh:

sshpass -p password ssh -T root@$line

La ligne "Avertissement: aucun accès à tty" provient du shell du système distant. cshet tcshimprimera ce message dans certaines circonstances. Il est possible qu'il soit déclenché par quelque chose dans le .cshrcfichier ou similaire sur le système distant, en essayant d'accéder à une fonctionnalité qui nécessite un ATS.


4

Utilisez le code suivant,

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

C'est ce que j'ai essayé en premier. Mais cela ne me donne pas la sortie attendue.
Être Gokul

1

Si vos hôtes sont stockés comme suit dans server.txt

host1.tld
host2.tld
....

Vous pouvez

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

1

Le stdin n'est pas accessible à vos commandes à distance. Ce que vous pouvez faire est d'utiliser l'indicateur "-s" de bash pour lire les commandes depuis stdin:

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

Donc, cela devrait faire ce que vous voulez:

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

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


1

Cela fonctionne très bien pour moi:

 # 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

notez que l'utilisation -t -tau lieu de -Tpour éviter l'erreur

Le pseudo-terminal ne sera pas alloué car stdin n'est pas un terminal


1
Vous devez lire sur le formatage. Votre réponse est peut-être excellente, mais pour l'instant elle est à peu près illisible.
roaima

0

Je suppose que le ssh en mange le reste pour stdin. vous pouvez consulter la FAQ 89 de Bash pour plus de détails. Avec un FileDescriptor, les codes suivants devraient fonctionner selon vos attentes.

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

l'alternative est d'utiliser / dev / null pour ssh. FileDescriptor peut être ignoré. `pendant la lecture de la ligne; do sshpass -p password ssh root @ $ line </ dev / null << EOF .... done <server.txt`
Leon Wang
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.