Mit Bash prüfen ob das eigene Script gerade läuft

Die Problemstellung

Ein Script soll alle x Minuten laufen und eine bestimmte Tätigkeit auf dem Server ausführen.

Nun kann es vorkommen, dass das Script aber länger braucht als die Zeitspanne bis zum nächsten Aufruf desselben Scripts (z.B. Kopier und Backup Jobs, Mails abholen, …)

Natürlich sollte so ein Script dann nicht ein 2tes Mal gestartet werden sondern die Ausführung übersprungen werden. Zu diesem Zweck möchte ich hier ein kleines Bash Script zeigen, das genau diesen Zweck erfüllt.

Die Lösung

#!/bin/bash
#
# testpid.sh - demo script to show how to check if a script
# with the same name is currently running
#
# by Leo Eibler
# resources:
#    http://www.eibler.at
#    http://leo.sprossenwanne.at
#    http://www.nullpointer.at
#

# PID - pid of the current script
PID=$$
# SCRIPTNAME - current name of the script without directory prefix
SCRIPTNAME=`basename $0`
# PIDFILE - where to write the current pid
PIDFILE=/tmp/$SCRIPTNAME.pid

# ENDEXECUTION - if 1 then stop script, if 0 everything is ok and continue
ENDEXECUTION=0

if [ -f "$PIDFILE" ]
then
    RUNNINGPID=`cat "$PIDFILE"`
    echo "got pid from $RUNNINGPID from pidfile '$PIDFILE'"
    PROGRAMPID=`ps -e | grep "$SCRIPTNAME" | grep -v grep | awk '{print $1;}'`
    for PIDEL in $PROGRAMPID
    do
        echo "testing pid of running scripts '$PIDEL' == '$RUNNINGPID' from pidfile"
        if [ "$PIDEL" == "$RUNNINGPID" ]
        then
            echo "found PID $RUNNINGPID current running - end execution"
            ENDEXECUTION=1
            break
        fi
    done
fi

if [ "$ENDEXECUTION" == "1" ]
then
    echo "Current script '$SCRIPTNAME' already running (pid $RUNNINGPID) - end execution"
    exit 1
fi
# writing PID to pidfile
echo $PID > $PIDFILE

#
# ---- START ----
#

echo "do your stuff here ..."
sleep 5
echo "... end script"

#
# ---- END ----
#

# delete pidfile
rm $PIDFILE
exit 0

Die Erklärung

Zuerst holt sich das Script den eigenen Namen mit basename $0 ($0 würde ebenfalls den Pfad des Scriptaufrufs enthalten aber hier würde der spätere Aufruf von ps bzw. das automatische Erstellen und Auslesen des passenden pid-Files scheitern).

Mit dem Namen des Scripts wird dann versucht ein pid-File (welches die Process-ID des aktuell laufenden Scripts enthält) auszulesen. Der Pfad des pid-Files kann beliebig gewählt werden, jedoch muss das Script natürlich Schreibrechte auf die Datei besitzen.

Falls kein pid-File existiert kann das Script davon ausgehen, dass es derzeit nicht bereits läuft und seine eigentliche Arbeit aufnehmen.

Falls jedoch ein pid-File vorhanden ist, wird dieses ausgelesen und mit allen derzeit laufenden Process-IDs von Prozessen mit dem gleichen Namen wie das Script verglichen.

Wird hierbei eine Übereinstimmung gefunden, dann läuft das Script bereits und durch Setzen der Variable $ENDEXECUTION auf 1 wird der Abbruch signalisiert.

Dieser Vergleich mit den Process-IDs von Prozessen die bereits laufen ist deswegen wichtig, da es ja sein könnte, dass das Script beim vorherigen Aufruf zwar ein pid-File angelegt hat, aber danach abgebrochen wurde (z.B. manuell durch den Benutzer) und das pid-File dadurch nicht gelöscht wurde.

Ist die Überprüfung auf eine laufende Instanz negativ, muss zuerst das pid-File angelegt werden (Die Variable $$ enthält die pid des aktuellen Prozesses).

Nach Beendigung der Arbeit sollte danach das pid-File wieder gelöscht werden um einen sauberen Abschluss zu bilden.

Das Script als Download gibts hier.

 

Ähnliche Artikel:

HOWTO: Git-Integration in MantisBT

Die letzten Wochen habe ich euch Git näher gebracht und euch gezeigt wie ihr euch einen eigenen Git-Server aufsetzen könnt. Jetzt wollen wir noch Kapital daraus schlagen und Git mit einem Bugtracker verbinden. Ich nutze nun schon seit längerem MantisBT http://www.mantisbt.org welcher mithilfe von ein paar Plugins an Git angebunden werden kann. Dies ermöglicht es einem anhand von Commit Messages Tickets in MantisBT zu steuern und zB ein offenes Ticket zu schließen.

Die letzten Wochen habe ich euch Git näher gebracht und euch gezeigt wie ihr euch einen eigenen Git-Server aufsetzen könnt. Jetzt wollen wir noch Kapital daraus schlagen und Git mit einem Bugtracker verbinden. Ich nutze nun schon seit längerem MantisBT http://www.mantisbt.org welcher mithilfe von ein paar Plugins an Git angebunden werden kann. Dies ermöglicht es einem anhand von Commit Messages Tickets in MantisBT zu steuern und zB ein offenes Ticket zu schließen.

Das Plugin trägt den klingenden Namen Source Control Integration und wurde von John Reese geschrieben. MantisBT selbst setzt das Plugin ein und vermutlich nutzen sie dort auch die Git Variante seit dem Umstieg des Bugtrackers auf Github. Das Plugin selbst besteht aus einem Framework und verschiedene Module für diverse Web-SourceControl Derivate wie z.B. Gitweb, Github, WebSVN. Eine Anleitung wie man dieses Plugin installiert findet sich ebenfalls im Blog von John Reese.

Ich will meine Schritte bei der Installation hier auf Deutsch zur Ergänzung meiner Git Artikel ebenfalls erfassen.

Als erstes galt es das Plugin und seine Abhängigkeiten zu organisieren: Meta Programming und Source Control Integration die entprechenden Repos wurden natürlich per Git geladen und jeweils ins Mantis Plugin Verzeichnis geladen. Im Backend von Mantis konnten diese dann aktiviert werden. Die richtige Reihenfolge konnte ob entsprechend optisch hervorgehobener Abhängigkeiten nicht versemmelt werden.

Nun hat man einen neuen Hauptmenüpunkt: Repositories

In diesem gilt es nun einen Verweis auf sein GitRepository zu erstellen. Name und Typ ausgewählt und schon gehts über den Create Repository Button weiter

MantisBT Sourceintegration Create Repository
MantisBT Sourceintegration Create Repository

Auf der zweiten Seite muss man nun die Daten zum zu überwachenden Repository eintragen

MantisBT Sourceintegration Repository Details
MantisBT Sourceintegration Repository Details

Hierbei wird die URL die auf das Gitwebverzeichnis verweist erst als ganzes eingetragen und dann in Root und Projektteil aufgesplittet. Noch den Master Branch als zu überwachender Branch definiert und schon kanns losgehen. Mit einem klick auf das Repository und dann den Button „Import Latest Data“ kann die erfolgreiche Verbindung auch gleich ausgetestet werden.

Der Author empfielt nun einen Cronjob zB per curl einzurichten damit dieser Prozess automatisiert wird. Die ID ist über Mantisbt rauszufinden (Einfach die URL die Mantis nutzt anschaun)

curl http://example.com/mantisbt/plugin.php?page=Source/repo_import_latest&id=XX > /dev/null

Dabei bekomme ich leider eine Fehlermeldung die auf einen ungültigen Sicherheitstoken verweist. In einem Blog Eintrag von Chris Dornfeld habe ich jedoch einen angepassten URL Aufruf dazu gefunden, der nicht auf ein Repository eingeschränkt ist und den Import per Cronjob ermöglicht:

curl http://example.com/mantisbt/plugin.php?page=Source/import&id=all > /dev/null

Fertig aufgesetzt habe ich nun doch etwas Zeit gewonnen, die ich nun ins Projekt statt ins Projektmanagement stecken kann.

Sollten bei euch noch andere Probleme auftreten, möchte ich noch auf eine kleine Hilfestellung im Blog des Authors verweisen, vielleicht werdet ihr ja dort fündig.

Greets

Ähnliche Artikel:

HOWTO: Gitweb für Gitosis, oder wie der Git Server sichtbar wird

Nachdem ich hier erst letztens aufgezeigt habe wie man seinen eigenen Git Server mithilfe von Gitosis aufsetzt, möchte ich heute noch etwas tiefer in die Materie vordingen. Heute soll der Git Server visualisiert werden mithilfe von Gitweb.

Nachdem ich hier erst letztens aufgezeigt habe wie man seinen eigenen Git Server mithilfe von Gitosis aufsetzt, möchte ich heute noch etwas tiefer in die Materie vordingen. Heute soll der Git Server visualisiert werden mithilfe von Gitweb.

Gitweb

Im Prinzip ist Gitweb recht flott installiert wenn man auf die Paketverwaltung der Distribution seines Vertrauens setzt. In meinem Beispielfall ist das Debian und mittels

$ aptitude install gitweb

wird die Software installiert. Damit Gitweb auf die eigenen Repositories zugreifen kann muss natürlich die Konfiguration /etc/gitweb.conf angepasst werden:

# path to git projects (.git) - hier auf das bei der installation von gitosis eventuell angepasste Verzeichnis linken
$projectroot = “/home/git/repositories/”;

# directory to use for temp files
$git_temp = “/tmp”;

# target of the home link on top of all pages
#$home_link = $my_uri || “/”;

# html text to include at home page
$home_text = “indextext.html”;

# file with project list; by default, simply scan the projectroot dir.
# $projects_list = $projectroot;

# Point to projects.list file generated by gitosis. - Hier ist wieder ein anpassung erforderlich wenn das homeverzeichnis wie bei unserem Beispiel angepasst wurde
$projects_list = “/home/git/gitosis/projects.list”;

# stylesheet to use
$stylesheet = “/gitweb.css”;

# javascrip code for gitweb
$javascript = "gitweb.js";

# logo to use
$logo = “/git-logo.png”;

# the ‘favicon’
$favicon = “/git-favicon.png”;

# A list of base urls where all the repositories can be cloned from.
# Easier than having per-repository cloneurl files.
@git_base_url_list = (’git://git.host.example’);

#$strict_export = “true”;

$projectroot – der Pfad zu den von gitosis erzeugten Repositories, in unserem fall /home/git/repositories;
$projects_list – damit wird gitweb gezeigt welche Repos vorhanden sind, entweder indem man auf das root Verzeichnis verweist oder auf eine Datei die eine Liste der Repositories beinhaltet. Verweist man auf die von gitosis erzeugte Projektliste “/home/git/gitosis/projects.list”; kann man über die Konfiguration von gitosis gezielt steuern, welche Repos angezeigt werden sollen.
Projekte die nicht angezeigt werden können mit obiger Konfiguration trotzdem noch durch direkten Aufruf über die Adressliste des Browsers erreicht werden. Soll auch dieser Aufruf unterbunden werden muss man den strict_export parameter auf true setzen, einfach dazu das Kommentarzeichen entfernen.

Nun muss noch im Webserver, in meinem Falle Apache2, richtig konfiguriert werden. Dazu habe ich eine eigene virtuelle Domain eingepflegt in folgender Datei /etc/apache2/sites-available/gitweb:

<VirtualHost *:80>
    ServerAdmin john@example.com
    DocumentRoot /var/cache/git
    ServerName git.example.com
    Alias /gitweb.css /usr/share/gitweb/gitweb.css
    Alias /git-favicon.png /usr/share/gitweb/git-favicon.png
    Alias /git-logo.png /usr/share/gitweb/git-logo.png
    ScriptAlias / /usr/lib/cgi-bin/gitweb.cgi
</VirtualHost>

Abschließend muss noch der Benutzer des Webservers www-data der gitosis gruppe hinzugefügt werden, damit der lesende Zugriff erfolgen kann. Danach wird die neu erstellte Subdomain noch aktiviert

$ a2ensite gitweb

Und Apache neu gestartet

$ /etc/init.d/apache2 reload

Wer cgi noch enabeln muss sollte danach nicht vergessen Apache ganz neu zu starten

$ /etc/init.d/apache2 restart

Und schon sollte der eigene Gitweb Zugriff fertig aufgesetzt sein.

Gitweb in der Gitosisconf

Fehlt natürlich noch die Konfiguration der Repositories um einzelne Projekte in Gitweb auszublenden

Im allgemeinen Bereich definiert hier der vorsichtige User folgendes:

[gitosis]
daemon = no
gitweb = no

Damit schließt man prinzipiell alle Projekte von der Ansicht in Gitweb aus. So wechselt man von einem Opt-Out Verfahren bei dem bei jedem Repo angegeben hätte werden müssen dass es nicht angezeigt werden soll, zu einem Opt-In, bei dem man sich bewusst für das anzeigen in Gitweb entscheiden muss.

Will man nun zB das Repository test in Github angeboten bekommen ist folgender Eintrag notwendig:

[repo test]
description = A repository where tests can take place
owner = testuser
daemon = no
gitweb = yes

Viel Spaß mit Git im Web!

Ähnliche Artikel:

HOWTO: Gitdaemon für den eigenen Gitserver

Will man seinen Gitosis – Gitserver etwas öffentlicher gestalten und der Allgemeinheit lesenden Zugriff auf seine Repositories gewähren will, dem steht das git Protokoll zur Auswahl. Der entsprechende Daemon ist unter Debian denkbar leicht zu installieren

Will man seinen Gitosis – Gitserver etwas öffentlicher gestalten und der Allgemeinheit lesenden Zugriff auf seine Repositories gewähren will, dem steht das git Protokoll zur Auswahl. Der entsprechende Daemon ist unter Debian denkbar leicht zu installieren

$ aptitude install git-daemon-run

Der Git Daemon verwendet jedoch nicht die üblichen /etc/init.de/ Runscripte sondern nutzt runit/runsv. Ein entsprechender Symlink hilft da alten Gewohnheiten schnell mal auf die Sprünge:

$ ln -s /usr/bin/sv /etc/init.d/git-daemon

Abschließend noch die Konfiguration /etc/sv/git-daemon/run an die Pfade von Gitosis angepasst (Hier als Beispiel mit dem angepassten Home Verzeichnis aus dem dazugehörigen Gitosis Tutorial):

#!/bin/sh
exec 2>&1
echo ‘git-daemon starting.’
exec chpst -ugitdaemon "$(git --exec-path)"/git-daemon --verbose --reuseaddr --base-path=/home/git/repositories /home/git/repositories

–reuseaddr ermöglicht es dem gitserver neu zustarten ohne auf bestehende Verbindungen rücksicht nehmen zu müssen und auf ein Timeout warten zu müssen.

Und schon steht dem giten über das eigene Protokoll nichts mehr im Wege. Außer vielleicht die Firewall, da brauchts ein extra Löcherl auf Port 9418.

Gitosis

In Gitosis gilt es nun noch den Git Daemon zu konfigurieren:
Der allgemeine Teil erhält ein generelles Opt-Out:

[gitosis]
daemon = no

Einzelne Repositories werden dann aktiv geschalten:

[repo test]
description = A repository where tests can take place
owner = testuser
daemon = yes

git://git.example.org/gutes_gelingen.git

Ähnliche Artikel:

HOWTO: Git Commands – ein Überblick

Ein Überblick über die wichtigsten Kommandos in Git zur Versionsverwaltung. Branchen, Taggen, an den Server senden. Alles ist abgedeckt

Von Git hab ich hier ja schon ein paar mal geschrieben. Gestern war dann sogar ein Howto für den eigenen Git Server an der Reihe. Damit wir nun auch damit arbeiten können möchte ich hier kurz und knackig die wichtigsten Git Befehle anführen:

Allgemein

Um ein komplett neues Projekt lokal anzulegen, erst das Verzeichnis anlegen, dann in das Verzeichnis wechseln und abschließent Git initialisieren

$ git init

Um das Repository auszuchecken

$ git clone gitosis@example.com:repository.git

Um zu sehen was sich lokal getan hat und noch nicht commited wurde

$ git status

Um Änderungen lokal zu commiten

$ git commit -am „Commit Description“

Das Git log ansehen

$ git log
$ git log –pretty=oneline
$ git log –date=short –pretty=format:“%ad: %s“ –since=“4 month ago“

Um zu sehen was sich am Server getan hat

$ git log –no-merges origin/master

Um den eigenen Datenbestand mit den letzten Änderungen vom Server abzugleichen:

$ git fetch origin
$ git merge origin/master

$ git pull origin master

Um seine Änderungen auf den Server zu laden in den Master-branch

$ git push origin master

Branches

Einen Branch anlegen oder zu ihm wechseln

$ git checkout -b branchname

Auf einen Branch wechseln (Legt keinen neuen an wenn nicht vorhanden)

$ git checkout branchname

Einen Branch auf den Server laden

$ git push origin branch

Einen Branch mit dem aktuell ausgecheckten Branch mergen

$ git merge branchname

Einen Branch lokal löschen

git branch -d branchname

Einen Branch am Server löschen

$ git push origin :branchname

Tags

Einen Tag anlegen

$ git tag -a tagname -m „tag description“

Einen Tag zum Server schicken

$ git push origin tag tagname

Alle Tags zum Server schicken

$ git push origin –tags

Einen Tag löschen

$ git tag -d tagname

Einen Tag am Server löschen

$ git push origin :tagname

Commitverwaltung

Ein Commit zurücknehmen

$ git reset –hard HEAD^

Mehrere Commits zurücknehmen (zB 3)

$ git reset –hard HEAD^^^
$ git reset –hard HEAD~3

Patch für Server erzeugen

$ git format-patch origin/master

Patchfiles für letzten 3 Commits erzeugen

$ git format-patch HEAD^^^

Patchfile einspielen

$ git am < patchfile

Was vergessen? Ab in die Kommentare damit. Viel Erfolg beim Versionsverwalten!

Eine gute Quelle für den Einstieg in Git ist unter anderem: http://de.gitready.com/

Ähnliche Artikel: