# ssh client in (bash) Schleife klappt nicht

## slick

Ich möchte auf n Rechnern, zu denen ich eine SSH Verbindung aufbauen kann, einen Remote Befehl ausführen. Hier exemplarisch "hostname" um zu sehen auf welchem Rechner der Befehl ausgeführt wird.

Die Liste der Hosts steht in der Datei "all.txt", jeweils ein Host je Zeile. Verbindungsaufbau klappt einzeln dank Schlüsseln sofort und ohne Nutzerinteraktion problemlos.

Allerdings klappt das nicht in folgender Schleife:

```
cat all.txt | while read c ; do ssh $c hostname  ; done
```

Da wird die Schleife ohne Fehlermeldung nach dem ersten Host beendet. Warum? Wie mach ichs richtig?

----------

## firefly

Funktioniert die schleife überhaupt richtig?

sprich was wird ausgegeben wenn du folgendes machst?

```
cat all.txt | while read c ; do echo "hostname: $c"   ; done
```

----------

## slick

Dann gibt er alle Hostname aus der Datei aus.

Also ich hatte mal anfangs eine Fehlermeldung, die könnte man so interpretieren das er versucht hat alle Host-Zeilen nach der ersten als Befehl auf dem ersten Host auszuführen.

----------

## firefly

also es kommen x-mal "hostname:<zeile aus text datei>" ausgaben?

----------

## Finswimmer

Versuch die ssh-Sache mal in einem Extra-Programm zu machen:

cat all.txt | while read c ; do ./execute-remote-script $hostname  ; done

Damit sollte es zumindest nicht passieren, dass die folgenden SSH-Kommandos versucht werden auf der ersten Remote-Maschine auszuführen.

in execute-remote-script:

ssh root@$1 /path/to/cmd

Tobi

----------

## mv

Vermutlich versucht ssh selbst von stdin zu lesen. Du musst also für ssh die Standardeingabe umleiten:

```
cat all.txt | while read c

do  ssh ... </dev/tty

done
```

Oder Du benutzt einen anderen Filedescriptor. Dann brauchst Du auch kein useless use of cat:

```
exec 3< all.txt && while read c <&3

do ssh ...

done

exec 3<&-
```

----------

## lxg

Steht der Befehl (sofern er nicht nur aus einem Wort besteht) denn in Anführungszeichen?

Übrigens, folgende Variante würde ich empfehlen:

```
for c in $(cat all.txt); do ssh $c "hostname"; done
```

Und zum Testen:

```
MYHOST="example.com"; ssh $MYHOST "Befehl mit Parametern"
```

----------

