ubuntuusers.de

Inhalt einer Variable in Shell testen

Status: Ungelöst | Ubuntu-Version: Ubuntu 19.04 (Disco Dingo)
Antworten |

Austi

Anmeldungsdatum:
25. August 2019

Beiträge: Zähle...

Hallo, ich bin neu in diesem Forum, und kann eine Problem nicht lösen. Ich habe eine Javaprogramm geschrieben das in einigen Fällen beendet wird. Mit eime Shellscript das mit Cronjob ausgefügrt wird will ich das Programm wieder neu starten. Nun zu meinem Problem: Das Script das ich geschrieben haben überprüft nicht zuverlässig ob das Programm läuft.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#! /bin/sh

x= pidof java;

echo $x;
 
if [ -z $x ]

then

	echo "Process läuft nicht"

else

	echo "Process läuft "

fi

exit 0

Wer kann mir sagen was ich falsch mache? Ich Danke euch allen für die Mühe

Bearbeitet von ChickenLipsRfun2eat:

Bitte verwende in Zukunft Codeblöcke, um die Übersicht im Forum zu verbessern!

ChickenLipsRfun2eat Team-Icon

Anmeldungsdatum:
6. Dezember 2009

Beiträge: 12067

Hallo und willkommen auf uu.de!

Als Startpunkt gibt es hier den Shell/Bash-Skripting-Guide für Anfänger.

Kurz mal zu cronjobs: Diese werden ggf. ohne Pfad-Variable verwendet, so dass es immer sicherer ist den vollen Pfad (wie /bin/pidof anstatt pidof) zu verwenden.

Für dein Vorhaben eignet sich aber eher eine systemd/User Units, die auf Änderungen deines Programms reagiert.

Deine Abfrage würde zudem auch jeden Java-Prozess erkennen, nicht nur dein Programm. Starte mal mehrere und gib pidof java im Terminal ein. Da bekommst du dann eine Liste an Prozessen.

Austi

(Themenstarter)

Anmeldungsdatum:
25. August 2019

Beiträge: 2

Danke für deine Hinweise.

Auf dem System läuft nur diese eine JAvaprogramm. Es hat die Aufgabe den ganzen Tag Daten zu Speichern. So tief bin ich nicht in Linux um alles genau zu vestehen.

Frage mich aber trotz allem wie ich den Inahlt der Variable "x" überprüfen kann. Danke

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11248

Wohnort: München

Du hast da mehrere Syntax- und Logikfehler in deinem Skript. In der Shell darf es keine Leerzeichen um das Gleichheitszeichen bei der Variablenzuweisung geben und du musst Variablen quoten, wenn du testen willst, ob sie leer sind. Um die Ausgabe eines Befehls einer Variablen zuzuweisen musst du ihn in einer Subshell ausführen. Strichpunkte am Zeilenende sind überflüssig. Und ein exit 0 am Ende ist nur notwendig, wenn man erzwingen will, dass der Exit-Code 0 ist statt dem Exit-Code des letzten Befehls zu entsprechen.

Wenn man das mal überarbeitet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#! /bin/sh

x="$(pidof java)"
echo "$x"
 
if [ -z "$x" ]
then
    echo "Process läuft nicht"
else
    echo "Process läuft"
fi

Das ist aber immer noch umständlich, denn eigentlich genügt es den Exit-Code von pidof auszuwerten:

1
2
3
4
5
6
7
#! /bin/sh
if pidof java
then
    echo "Process läuft nicht"
else
    echo "Process läuft "
fi

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17604

Wohnort: Berlin

1
x= pidof java;

ist jedeenfalls in 2facher Hinsicht falsch:

1. Bei Zuweisungen in der Shell gibt es, im Gegensatz zu vielen anderen Programmiersprachen, keinerlei Toleranz hinsichtlich der Leerzeichen ums Gleichheitszeichen, weder davor, noch danach. Unser Zwischenstand wäre daher:

1
x=pidof java;

aber das ist leider immer noch falsch. Du möchtest die Ausgabe des Programms dem x zuweisen - dann brauchst Du - ich glaube der Fachausdruck ist - command substitution:

1
2
3
x=$(pidof java);
# oder
x=$(pidof java;)

Das würde bei einem laufenden Javaprozess dann funktionieren. Mit dem Semikolon ist es auch anders als in C, C++, Java und einigen anderen Sprachen, aber damit sind die Shellsprachen nicht alleine: Es wird benötigt um innerhalb einer Zeile mehrere Befehle voneinander abzugrenzen und ist wie ein Zeilenumbruch. Wenn Du aber eh danach einen Zeilenumbruch hast, dann brauchst Du es nicht.

1
x=$(pidof java)

Apropos "brauchst Du nicht": exit 0 als letzten Befehl brauchst Du auch nicht, außer Du willst einen vorigen Fehler verbergen. Es ist wie mit einem Roman, bei dem nach dem letzten Satz "Ende." im Buch steht. Das merkt der User auch so, dass da Ende ist, und zwar daran, dass nichts mehr kommt. Exit brauchst Du um einen Endecode zu erzwingen, der Fehler etwa kaschiert, was sehr selten eine gute Idee ist, oder einen Fehler anzeigt, wo keiner war - auch meist kein hilfreiches Vorgehen. Ansonsten braucht man exit um vorzeitig die Bearbeitung zu beenden.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11248

Wohnort: München

Austi schrieb:

Auf dem System läuft nur diese eine JAvaprogramm. Es hat die Aufgabe den ganzen Tag Daten zu Speichern. So tief bin ich nicht in Linux um alles genau zu vestehen.

Dann brauchst du eigentlich nur eine Systemd-Unit, die dieses Programm verwaltet. Die kann selbständig prüfen, ob das Programm läuft und es automatisch wieder starten, wenn es sich beendet hat (wenn man will auch abhängig vom Exit-Code).

Das Grundgerüst für eine solche Unit könnte so aussehen (ggf. muss man noch Abhängigkeiten wie z.B. eine fertig konfigurierte Netzwerkverbindung usw. angeben oder den Typ ändern, falls das Programm beim Start forkt):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#/etc/systemd/system/my-data-collector.service
[Unit]
Description=Run my data collection tool

[Service]
Type=simple
ExecStart=/pfad/zum/programm
Restart=always

[Install]
WantedBy=multi-user.target

Die Unit aktivierst du dann mit

systemctl enable --now my-data-collector.service 

Es ist normalerweise wesentlich weniger Aufwand eine Systemd-Unit zu erstellen als ein fehlerfreies Shell-Skript zu schreiben, das die Prozessüberwachung und -verwaltung übernimmt.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

Austi schrieb:

Ich habe eine Javaprogramm geschrieben das in einigen Fällen beendet wird. Mit eime Shellscript das mit Cronjob ausgefügrt wird will ich das Programm wieder neu starten. Nun zu meinem Problem: Das Script das ich geschrieben haben überprüft nicht zuverlässig ob das Programm läuft.

Wenn Du es mit einem Skript machen willst, ist das einfachste, einfach den Java-Prozess aus dem Skript zu starten:

1
2
3
while true; do
  java -Xmx512m foo.bar.Main
done

Wann auch immer die JVM terminiert, wird sie sogleich neu gestartet. Ich stimme aber zu, dass eine Systemd-Unit besser ist.

Antworten |