Hallo, On Wed, 03 Sep 2003, Bernd Tannenbaum schrieb:
2) Ruft jemand das script auf, prüft es zuerst ob es etwas in die Datei schreiben kann. Falls ja, schreibt es etwas shell-spezifisches (die tty-Nummer) in die Datei und in eine Variable und ändert die Rechte in Nur-lesen.
Warum ist dir die PID nicht eindeutig genug? Achso: Pid-/Lock- und aehnliche Dateien gehoeren nach /var: ==== FHS 2.0 ==== 5. The /var Hierarchy /var -- Variable data | +-lock Lock files +-run Files relevant to running processes +-state Variable state information [..] Applications should generally not add directories to the top level of /var. Such directories should only be added if they have some system- wide implication, and in consultation with the FHS mailing list. ==== (der letzte Absatz speziell fuer Jan ;) Der Ansatz von Jan ist gut, ich wuerde sowas in der Art hier verwenden: ==== nur ein wenig getestet ==== #! /bin/sh LOCKFILE="/var/lock/assh.lck" STATEDIR="/var/state/assh" PORTFILE="${STATEDIR}/assh.ports" DEFAULTPORT="20000" LASTPORT="20010" TIMEOUT=60 # Verzeichnis $STATEDIR muss existieren und fuer uns schreibbar sein if test -d "$STATEDIR" && test -w "$STATEDIR" then : else cat <<EOF >&2 No such directory or cannot write in '$STATEDIR' Please contact your system-administrator to create this directory with appropriate permissions. EOF exit 2 fi # und $PORTFILE muss existieren und schreibbar sein test -f "$PORTFILE" && test -w "$PORTFILE" || echo "$DEFAULTPORT" > "$PORTFILE" # bei Abbruch aufraeumen... trap "release_port $port; release_lock;" 1 2 3 15 get_lock() { # Pruefen, ob $LOCKFILE existiert und lesbar ist if test -r "$LOCKFILE" then # wenn die Datei existiert: pruefen ob Prozess noch aktiv ist # wenn ja, dann warten t=1 while ps -p `cat $LOCKFILE` >/dev/null 2>&1 do sleep 1 t=`expr $t + 1` test $t -gt $TIMEOUT && exit 1 done fi # LOCKFILE existiert nicht oder Prozess ist gestorben, (ggfs. anlegen) # und eigene PID reinschreiben echo $$ >$LOCKFILE || { echo "cannot write to '$LOCKFILE'" >&2; exit 2; } } release_lock() { test "x`cat \"$LOCKFILE\" 2>/dev/null`" = "x$$" && rm -f "$LOCKFILE" } get_port() { get_lock || exit 1 used_ports="`cat \"$PORTFILE\" | grep -v '^$'`" if test -z "$used_ports" then new_port="$DEFAULTPORT" else p="$DEFAULTPORT" while echo "$used_ports" | grep -q "$p" && test $p -lt $LASTPORT do p=`expr $p + 1` done if test $p -ge $LASTPORT then echo "All ports in use, please try again later." >&2 exit 1 fi new_port="$p" fi # add new port to $PORTFILE echo "$used_ports $new_port" | sort -un | grep -v '^$' > $PORTFILE release_lock || exit 1 # return new port echo "$new_port" } release_port() { get_lock || exit 1 used_ports="`cat $PORTFILE`" echo "$used_ports" | grep -v "$port\|^$" | sort -un > $PORTFILE release_lock || exit 1 } # freien port finden port=`get_port` # autossh aufrufen /usr/bin/autossh -M $port "$@" # und wieder freigeben release_port $port ==== Ups, grad seh ich ne moegliche "Luecke" (port ist leer) in "release_port()"... Da bin ich jetzt aber zu muede zu... -dnh PS: etwas eigenartige Konstruktionen (if ... ; then : ; else ... ; fi) sind dadurch bedingt, dass ich bourne-shell kompatibel sein will und die ash zum testen verwendet habe -- und deren if-builtin kann kein 'if ! ...' -- We are gathered here today for a solemn occasion, to honor the memory of a good joke which fell victim to a crude, pointless rebuttal by a poster temporarily bereft of sanity and decorum. -- David P. Murphy