Bash: Wie Prozess zur PID finden?
In einigen meiner Bash-Skripte habe ich drei Funktionen zum sauberen Locken, die ich aus dem Buch "Raffinierte Shell Scripts" habe:
Code:
sleeptime="1" # sleeptime for creating the lockfile
retries="10" # default number of retries of creating the lockfile: 10 (should be > locktimeout*sleeptime)
locktimeout="5" # default timeout : 5 s. The lockfile will be removed
# by force after locktimeout seconds have passed
lockdir="/var/tmp"
lockfile="$lockdir/lockfile.beispiel" # lockfile name
# ascertain whether we have lockf or lockfile system apps
check ()
{
if [ -z "$(which lockfile | grep -v '^no ')" ] ; then
echo "$0 failed: 'lockfile' utility not found in PATH." >&2
exit 1
fi
}
# make lockifle
lock ()
{
if [ -f $lockfile ]; then
if kill -0 $(cat $lockfile) 2> /dev/null; then
echo "The locking executable with pid $(cat $lockfile) appears to be already running."
echo "Please check $lockfile if you think this is an error."
exit 1
else
echo "The locking executable with pid $(cat $lockfile) appears to have completed without cleaning up its lockfile."
echo "Removing that lockfile "$lockfile"."
rm -f "$lockfile"
fi
fi
# create the lockfile; wait
if ! lockfile -$sleeptime -r $retries -l $locktimeout "$lockfile" 2> /dev/null; then
echo "$0: Failed: Couldn't create lockfile in time" >&2
exit 1
fi
chmod u+rw "$lockfile"
# store the pid
echo $$ > "$lockfile"
chmod u-wx "$lockfile"
}
# cleanup
unlock ()
{
rm -f "$lockfile"
}
Allerdings gibt's damit das Problem, das beim lock() zufällig ein ganz anderer Prozess laufen kann, der die PID hat, die im Lockfile steht.
Und Gemäß Murphy's Law wird mir das sicherlich irgendwann passieren.
Man kann das Problem aber beseitigen, indem man den Namen zu der PID überprüft.
Dabei gibt's aber das Problem, das bei Bash-Skripten am Anfang der Kommandozeile, die ps anzeigt, erstmal /bin/bash steht; ein einfacher String-Vergleich reicht also nicht. Dazu kommt, das am Ende auch etwas stehen kann; beispielsweise
/dev/ttyS0 | tee data ; } 3>&2 2>&1 1>&3 | tee log.err
.
Wie also kann ich beim lock() überprüfen, ob der Prozess, der zu der PID im Lockfile gehört, einen bestimmten Namen hat (enthält); beispielsweise $0 (Name des aktuellen Shellskripts) oder ein String wie "beispiel.sh"? :confused: