Dateitest remote per ssh

B

Burkin

Grünschnabel
Hallo

Ich möchte aus einem Shell-Skript heraus eine Dateitest auf einem Rechner ausführen auf dem ich per ssh eingeloggt bin. Der Loginvorgang erfolgt per Public-Key Authentifizierung und funktioniert problemlos.

Jedoch erzeugt folgender Befehl keine Ausgabe

ssh 192.168.27.3 test -s /var/run/script.pid

obwohl die Datei /var/run/script.pid auf dem Zielrechner (192.168.27.3) vorhanden und nicht leer ist.

Kann mir bitte mal jemand sagen warum

Danke
 
hi,

was meinst du mit, erzeugt keine Ausgabe? Test erzeugt auch keine Ausgabe... man test...
Du muesstest schon noch den return code des letzten befehles abfragen, auf der bash mit echo "$?".

edit:
Oder eben schnell eine if Abfrage dafuer schreiben: "if [ -s bla.pid ]; then echo 'exists'; fi"

mfg,
bytepool
 
Zuletzt bearbeitet:
Wie ist dein Script aufgebaut? Gib mal den Quellcode.

Probier mal cat /var/run/script.pid

Kommt dann ne ausgabe?

Edit: Ah, bytepool war schneller. Ach "test" ist ein programm? Ich dachte jetzt der hat sein script einfach test genannt :D
 
Hier der relevante Auszug aus dem Script
vieleicht kann man damit das ganze etwas besser verstehen

show)
for DIALER in ${ALLDIALERS[*]}
do
AA=0
if [ -s /var/run/$DIALER.pid ]
then
ZEIT=`date --reference=/var/run/$DIALER.pid +%F/%T`
PID=`cat /var/run/$DIALER.pid`
RUN=`ps $PID`
echo -e "\033[40;01;32m$DIALER is running with PID $PID since $ZEIT\033[0m"
FA=`grep FIRSTAGENT /etc/init.d/$DIALER|grep =`
echo -e "\033[40;01;32m$FA \033[0m"
else
for HOST in ${HOSTS[*]}
do
RPID=`ssh $HOST cat /var/run/$DIALER.pid`
echo "RemotePID =" $RPID
if [ `ssh $HOST test -s /var/run/$DIALER.pid` ]
then
echo $DIALER is running on $HOST
AA=1
fi
done
if [ $AA = 0 ]
then
echo $DIALER is not running
FA=`grep FIRSTAGENT /etc/init.d/$DIALER|grep =`
echo $FA
fi
fi
# echo $RUN
done
;;

und hier die erzeugten Ausgaben

/etc/init.d/all_dialer show
RemotePID = 4826
cat: /var/run/predicall_ibpl2.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_ibpl2 is not running
FIRSTAGENT1=2000 FIRSTAGENT2=2000
cat: /var/run/predicall_csc.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_csc.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_csc is not running
FIRSTAGENT1=4000 FIRSTAGENT2=4200
predicall_pl3 is running with PID 5432 since 2007-12-16/03:00:06
FIRSTAGENT1=5400
FIRSTAGENT2=5500
cat: /var/run/predicall_kpm.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_kpm.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_kpm is not running
FIRSTAGENT1=5000 FIRSTAGENT2=5100
predicall_mdm is running with PID 5511 since 2007-12-16/03:00:11
FIRSTAGENT1=4000
FIRSTAGENT2=4200
predicall_csm is running with PID 5670 since 2007-12-16/03:00:21
FIRSTAGENT1=5800
FIRSTAGENT2=5900
predicall_dcw is running with PID 5692 since 2007-12-16/03:00:26
FIRSTAGENT1=1000
FIRSTAGENT2=1300
predicall_pl5 is running with PID 5714 since 2007-12-16/03:00:31
FIRSTAGENT1=5600
FIRSTAGENT2=5700
cat: /var/run/predicall_pl7.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
RemotePID = 6185
predicall_pl7 is not running
FIRSTAGENT1=6000 FIRSTAGENT2=6150
RemotePID = 5087
cat: /var/run/predicall_test.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_test is not running
FIRSTAGENT1=3400 FIRSTAGENT2=3700
predicall_test1 is running with PID 5743 since 2007-12-16/03:00:36
FIRSTAGENT1=5200
FIRSTAGENT2=5300
cat: /var/run/predicall_tlp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_tlp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_tlp is not running
FIRSTAGENT1=1800 FIRSTAGENT2=1900
cat: /var/run/predicall_tmp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_tmp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_tmp is not running
FIRSTAGENT1=4800 FIRSTAGENT2=4900
predicall_vd01 is running with PID 5769 since 2007-12-16/03:00:41
FIRSTAGENT1=1000
FIRSTAGENT2=1200
cat: /var/run/predicall_vdgfp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_vdgfp.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_vdgfp is not running
FIRSTAGENT1=2000 FIRSTAGENT2=2200
RemotePID = 5148
cat: /var/run/predicall_ibpl3.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_ibpl3 is not running
FIRSTAGENT1=2000 FIRSTAGENT2=2000
cat: /var/run/predicall_tmad.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_tmad.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_tmad is not running
FIRSTAGENT1=3200 FIRSTAGENT2=3300
cat: /var/run/predicall_pl1.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
RemotePID = 6156
predicall_pl1 is not running
FIRSTAGENT1=1000 FIRSTAGENT2=1200
cat: /var/run/predicall_ubs.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
RemotePID = 6102
predicall_ubs is not running
FIRSTAGENT1=6000 FIRSTAGENT2=6400
cat: /var/run/predicall_cnb.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
cat: /var/run/predicall_cnb.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_cnb is not running
FIRSTAGENT1=3600 FIRSTAGENT2=3700
RemotePID = 5062
cat: /var/run/predicall_fms.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_fms is not running
FIRSTAGENT1=1600 FIRSTAGENT2=1700
RemotePID = 4913
cat: /var/run/predicall_ibpl1.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_ibpl1 is not running
FIRSTAGENT1=2000 FIRSTAGENT2=2000
RemotePID = 5112
cat: /var/run/predicall_ibpl7.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_ibpl7 is not running
FIRSTAGENT1=2000 FIRSTAGENT2=2000
RemotePID = 5039
cat: /var/run/predicall_itc.pid: Datei oder Verzeichnis nicht gefunden
RemotePID =
predicall_itc is not running
FIRSTAGENT1=6600 FIRSTAGENT2=6700
 
hi,

koenntest du das mal in code tags packen und vernuenftig einruecken? Das kann doch so keiner lesen...

Und du wunderst dich jetzt, dass
Code:
if [ `ssh $HOST test -s /var/run/$DIALER.pid` ]
nicht funktioniert, oder wie?

Das ist doch relativ logisch... Gehen wir das mal Schritt fuer Schritt durch. Du laesst die Bash "ssh $HOST test -s /var/run/$DIALER.pid" ausfuehren, und das ergebnis wird in dieser Zeile eingesetzt. Ich sagte weiter oben schon, dass test keine Ausgabe auf stdout erzeugt. D.h. die shell wird `ssh $HOST test -s /var/run/$DIALER.pid` mit "" substituieren, weil das die Ausgabe dieses Befehles ist.
Mit anderen Worten, die Zeile lautet nach der Ersetzung:
Code:
if [ ]

Noch fragen? ;)

edit:
Um das ans Laufen zu kriegen wie du dir das vorstellst, koenntest du das z.B. so machen:
Code:
if [ a"exists" = a$(ssh $HOST "if [ -s ${BLA}.pid ]; then echo 'exists';fi" ]) ]

mfg,
bytepool
 
Zuletzt bearbeitet:
Code:
if [ -s $(ssh $HOST /var/run/$DIALER.pid) ]
then
echo $DIALER is running on $HOST
sollte auch gehen
 
Code:
if [ -s $(ssh $HOST /var/run/$DIALER.pid) ]
then
echo $DIALER is running on $HOST
sollte auch gehen

Ehm, das gibt aber imho immer aus, dass $DIALER am rennen ist... Auch wenn die Datei nicht existiert.

edit:
Oder fuehrt zu Syntax Fehlern. Grund, siehe meinen Post weiter oben...

edit2:
Mhh, ok, ich gestehe ich verstehe das Verhalten von deinem Befehl nicht. Nach meinem Verstaendnis sollte dieser Befehl immer gar nix ausgeben, weil genau wie oben ein "" dafuer substituiert wird. Das ist aber nicht was passiert, erst bekomme ich entweder die Fehlermeldung "file not found" oder "permission denied", je nachdem ob die Datei existiert oder nicht, das ist klar. Aber in beiden Faellen ist der if Ausdruck wahr. Wieso? Koenntest du das mal erklaeren? Was gibt ssh im Fehlerfall an die Shell zurueck?

edit3:
Ok, Raetsel geloest ;)
'test -s ' ist immer wahr, warum auch immer. Aendert nix daran dass das keine Loesung ist.
Mhh, achso, macht ja eigentlich auch Sinn, die Datei "" exisitiert ja im Grunde auch in jedem Verzeichnis ;)

mfg,
bytepool
 
Zuletzt bearbeitet:
Danke an bytepool
Funktioniert nach Korrektur der Syntaxfehler hervorragend, dennoch ist mir unklar warum ich auf einem lokalen Systen offensichtlich ein TRUE zurück bekomme aber auf einem Remotesystem nicht. Werd mir dazu wenn ich Zeit hab mal die Manpage von test genauer durchlesen.
Sorry für den nicht formatierten Code, wurde duch copy and paste verändert, im realen Script ist er selbstverständlich eingerückt sonst sehe ich selbst nicht durch.

Also Danke nochmal
 
hi,

dennoch ist mir unklar warum ich auf einem lokalen Systen offensichtlich ein TRUE zurück bekomme aber auf einem Remotesystem nicht.

Ganz einfach, der Befehl den du an ssh uebergibst, wird lokal auf dem remotehost ausgefuehrt, und der stdout des Befehles wird dann per ssh wieder auf den localhost uebertragen. D.h. der exit code von test liegt auf dem remotehost, waehrend der exit code des letzten Befehls auf dem localhost der exit code von ssh ist.

Also wenn du ein
Code:
if ssh $host "test -s bla.txt"; then echo; fi
machst, wuerde if schauen ob ssh korrekt ausgefuehrt wurde, also ob der return code von ssh 0 war. Der exit code von dem Test ist fuer das Skript voellig irrelevant weil er auf der anderen Maschine ausgefuehrt wurde.

Jedenfalls ist das mein Wissensstand, ich kann mich irren, glaube es aber nicht.

Was du ausserdem verstehen musst, ist dass die command substitution zuerst ausgefuehrt wird, und wirklich nur den output auf stdout von dem ausgefuehrten Befehl in der Zeile einfuegt.

<edit>
Um das nochmal ein wenig zu verdeutlichen und Parallelen zu deinem urspruenglich verwendeten Kommando zu ziehen:
Code:
if [ $(test -s datei ) ]
wuerde genauso wenig funktionieren, eben weil test keine Ausgabe erzeugt die vom zweiten test interpretiert werden koennte.
</edit>

Ich hoffe das war halbwegs verstaendlich, das Prinzip ist im Grunde nicht so kompliziert, es ist nur nicht ganz leicht zu erklaeren.

Danke an bytepool
Gern geschehen :)

mfg,
bytepool
 
Zuletzt bearbeitet:
Hallo

Du kannst den Returnwert im remote manipulieren und übermitteln.
Das geht sogar direkt mit test, wenn du die Kurzform verwendest.
Hier mit ssh key und alias in der config.
Code:
ssh remotehost "test -e /var/log/foobar&&echo 0||echo 1"
Gibt 0 bei exist zurück, und 1 (false) bei not exist zurück.

Damit lässt sich das mit if auswerten.

Das mit dem Returnwert hat bytepool schon richtig erklärt. (ssh wert)

Gruß Wolfgang
 
Zuletzt bearbeitet:
hi,

stimmt, die Verknuepfung mit && und || ist in dem Fall nochmal einiges eleganter und leichter zu lesen als eine zweite if Verschachtelung. Sollte ich mir mal merken.
Die Benutzung mit numerischen Rueckgabewerten saehe dann so aus, richtig?
Code:
if [ 0 -eq $(ssh remotehost "test -e /var/log/foobar && echo 0 || echo 1") ]

Oder gibt es da noch einen Kniff wie man das vereinfachen kann den ich grad nicht sehe?

<kleinlaut>Du hast da uebrigens noch einen Tippfehler in deinem Code.</kleinlaut> ;)

mfg,
bytepool
 
Jo, Fiptehler sind mein Spezialgebiet. ;)

Passiert mir oft, wenn ich das so ungetestet reinschreibe.
Hinweise darauf gern gesehen.

Ja der simple und nachvollziehbare Gebrauch geht schon so wie oben gepostet.

Code:
if [ $(ssh hostname "test -e /var/log/foobar&&echo 0||echo 1") -eq 0 ];
then 
echo "true";
else 
echo "sorry not found";
fi
Hier wird nicht STDERR sondern STDOUT vom ssh-Befehl ausgewertet.

Hier geht auch noch die Kurzform, aber es soll ja nachvollziehbar bleiben.

Gruß Wolfgang
 

Ähnliche Themen

Ordnerinhalt als Textdatei - ls packt alles hintereinander

Samba 4 Gast Zugang unter Ubuntu funktioniert nicht

rsnapshot und ein Rechteproblem?

Windows clients können nicht mehr auf lange laufendes System zugreifen

Falsche Rechte gesetzt beim Anlegen von Ordnern via Samba-Client

Zurück
Oben