Discussion:
Bash-Skript, while-Schleife mit ssh
(zu alt für eine Antwort)
Alexander Skwar
2011-03-18 23:47:53 UTC
Permalink
Mir fällt nochwas ein…

Am 18.03.2011 um 19:00 schrieb Harald Weidner <hweidner-***@gmx.net>:

Hallo,

Ivo Engelhardt <***@gmail.com>:

cat daten.txt | while read varzeile
do
# Nun ist die Zeile in der Variable varzeile.
echo "${varzeile}"
ssh ***@serverurl "./befehl auf dem server mit ${varzeile} übergeben"
done

Dein Script startet die SSH Verbindung, aber beendet sie vermutlich
nicht.

Oder es beendet die Verbindung, aber der ./befehl hat vorher die gesamte
Standardeingabe bis zum EOF ausgelesen.

Das es übrigens zuerst an ssh und nicht am Remote ./Befehl liegt, kann man leicht daran erkennen, das die while Schleife auch dann abbricht, wenn man Remote nur zB "hostname" aufruft (also Einen Befehel, der nicht von stdin liest).

Musste ich jetzt noch unbedingt loswerden — „sooorrry“ :)

Alexander
Harald Weidner
2011-03-19 13:41:26 UTC
Permalink
Hallo,
Post by Alexander Skwar
Das es übrigens zuerst an ssh und nicht am Remote ./Befehl liegt, kann man
leicht daran erkennen, das die while Schleife auch dann abbricht, wenn man
Remote nur zB "hostname" aufruft (also Einen Befehel, der nicht von stdin
liest).
Tut es das?

***@local:~/test$ cat daten.txt
1
2
3
***@local:~/test$ cat loop.sh
#!/bin/bash
cat daten.txt | while read varzeile
do
echo "********* ${varzeile}"
ssh remote 'hostname'
done
***@local:~/test$ ./loop.sh
********* 1
remote
********* 2
remote
********* 3
remote

Wenn ich dagegen 'hostname' durch 'cat' ersetze, dann liest das Kommando auf
der Remote Seite die restlichen Zeilen der Eingabe.

***@local:~/test$ ./loop.sh
********* 1
2
3

"local" ist hier übrigens Squeeze, "remote" Lenny.

Wenn sich das Skript bei dir anders verhält, kann das zahlreiche Ursachen
haben. Hinter dem simpel aussehenden "ssh host command" kann sich auf der
Remote Seite durchaus viel Komplexität verbergen. Je nach Konfiguration des
sshd wird vielleicht /sbin/login aufgerufen. Es wird die Shell des Benutzers
gestartet, die möglicherweise Startup-Skripte wie z.B. ~/.bashrc abarbeitet.

Daher ist das Skript eine fragile Konstruktion und man sollte auf jeden Fall
ssh mit einer leeren Standardeingabe starten. Die Aussage, dass der ssh
Client von sich aus alles auf der Standardeingabe liest, ist aber nicht
richtig.

Gruß, Harald
--
Zum AUSTRAGEN schicken Sie eine Mail an debian-user-german-***@lists.debian.org
mit dem Subject "unsubscribe". Probleme? Mail an ***@lists.debian.org (engl)
Archive: http://lists.debian.org/im2bq6$1gl$***@m31s16.vlinux.de
Alexander Skwar
2011-03-19 15:11:41 UTC
Permalink
Hi!
Post by Alexander Skwar
Hallo,
Post by Alexander Skwar
Das es übrigens zuerst an ssh und nicht am Remote ./Befehl liegt, kann man
leicht daran erkennen, das die while Schleife auch dann abbricht, wenn man
Remote nur zB "hostname" aufruft (also Einen Befehel, der nicht von stdin
liest).
Tut es das?
Sonst hätte ich's nicht geschrieben ;)

MacBook-Pro:~ alex$ printf '1\n2\n3\n' | while read z; do echo $z ;
ssh pp hostname ; done
1
pp

MacBook-Pro:~ alex$ printf '1\n2\n3\n' | while read z; do echo $z ;
ssh pp hostname < /dev/null ; done
1
pp
2
pp
3
pp

Lokal: Mac OSX, Remote: Squeeze

Ist keine Spezialität von OSX, sondern habe
ich bisher überall so gehabt.
Post by Alexander Skwar
********* 1
remote
********* 2
remote
********* 3
remote
Nicht reproduzierbar. Hier bricht loop, wie
zu erwarten, nach dem ersten Durchlauf
ab.
Post by Alexander Skwar
Wenn sich das Skript bei dir anders verhält, kann das zahlreiche Ursachen
haben. Hinter dem simpel aussehenden "ssh host command" kann sich auf der
Remote Seite durchaus viel Komplexität verbergen. Je nach Konfiguration des
sshd wird vielleicht /sbin/login aufgerufen. Es wird die Shell des Benutzers
gestartet, die möglicherweise Startup-Skripte wie z.B. ~/.bashrc abarbeitet.
Unter welchen Umständen erreicht man denn ein
Verhalten, wie Du es oben demonstriert hat?
Post by Alexander Skwar
Daher ist das Skript eine fragile Konstruktion und man sollte auf jeden Fall
ssh mit einer leeren Standardeingabe starten. Die Aussage, dass der ssh
Client von sich aus alles auf der Standardeingabe liest, ist aber nicht
richtig.
Trotzdem ist es bisher aber bei mir unter
den verschiedensten Konstruktionen *immer*
so gewesen, das ssh direkt abgebrochen hat.
Meine Erklärung war (für mich) bisher, das
ssh alles auf stdin "weg"liest.

Alexander
--
↯    Lifestream (Twitter, Blog, …) ↣ http://alexs77.soup.io/     ↯
↯ Chat (Jabber/Google Talk) ↣ ***@gmail.com , AIM: alexws77  ↯
Alexander Skwar
2011-03-22 11:22:46 UTC
Permalink
Tach auch! ;)
Post by Alexander Skwar
while read varzeile
do
  # Nun ist die Zeile in der Variable varzeile.
  echo "${varzeile}"
übergeben"<  /dev/null
done<  daten.txt
Die Lösung ist nur suboptimal, da dabei komplett stdin verbogen wird und es beispielsweise nicht mehr möglich ist ein PW einzugeben o.ä.
Stimmt. *ICH* brauche solche Schleifen aber, um auf vielen
Hosts eine identische Aufgabe zu erledigen. Da wäre ein
manueller Eingriff (PW eingeben, …) "tödlich".
Außerdem ist es denkbar, dass man sich damit eine Endlosschleife gebaut hat.
Wie?
Beispiel: Beim Connect auf den Remotehost erscheint die Frage "Public-Key" bestätigen yes/no. Wenn dannn immer Null "0" in die Eingabe geschrieben wird, kommt der Prozeß wohl nicht mehr zum Ende.
--($ ~)-- ssh lics < /dev/null
Pseudo-terminal will not be allocated because stdin is not a terminal.
The authenticity of host 'race-lics (10.0.1.46)' can't be established.
RSA key fingerprint is 78:e1:92:9d:b5:a0:f1:d6:9b:13:c7:16:8b:3d:cc:a6.
Are you sure you want to continue connecting (yes/no)? n
Please type 'yes' or 'no': no
Host key verification failed.
       file=/home/user/xxxxfile
       exec 4< $file
       while read -u 4 varzeile ;
       do
           echo "$varzeile";
       done
Ja, die Lösung ist besser.

Alexander
--
↯    Lifestream (Twitter, Blog, …) ↣ http://alexs77.soup.io/     ↯
↯ Chat (Jabber/Google Talk) ↣ ***@gmail.com , AIM: alexws77  ↯
Loading...