ubuntuusers.de

Eigenes Script in /etc/init.d startet nicht beim Hochfahren

Status: Gelöst | Ubuntu-Version: Server 8.04 (Hardy Heron)
Antworten |

lukpor

Anmeldungsdatum:
26. September 2010

Beiträge: Zähle...

Ich schaffe es nicht, ein Script automatisch beim Hochfahren des Systems zu starten. Wenn ich es über die Konsole starte, funktioniert es einwandfrei.

Das Script liegt im Verzeichnis /etc/init.d . Von /etc/rc2.d aus ist es meiner Ansicht nach korrekt verlinkt mit S20name_des_scripts .

Das habe ich erledigt mit sudo update-rc.d name_des_scripts defaults

Ich finde auch nirgends eine Fehlermeldung in den logs.

tgsflash

Avatar von tgsflash

Anmeldungsdatum:
21. August 2010

Beiträge: 921

Wohnort: /home

hast du auch den Runlevel definiert der beim booten startet

adun Team-Icon

Avatar von adun

Anmeldungsdatum:
29. März 2005

Beiträge: 8606

Der Unterschied zwischen in der Konsole und beim Booten starten ist die Umgebung. Dein Skript verlässt sich wahrscheinlich darauf, dass $PATH gesetzt ist. Du kannst entweder die Umgebung setzen (dafür gibt es auch helper) oder aber du schreibst es so um, dass nur absolute Pfadangaben verwendet werden, wobei ich letzteres empfehlen würde.

lukpor

(Themenstarter)

Anmeldungsdatum:
26. September 2010

Beiträge: 5

tgsflash schrieb:

hast du auch den Runlevel definiert der beim booten startet

ja, 2

lukpor

(Themenstarter)

Anmeldungsdatum:
26. September 2010

Beiträge: 5

adun schrieb:

Der Unterschied zwischen in der Konsole und beim Booten starten ist die Umgebung. Dein Skript verlässt sich wahrscheinlich darauf, dass $PATH gesetzt ist. Du kannst entweder die Umgebung setzen (dafür gibt es auch helper) oder aber du schreibst es so um, dass nur absolute Pfadangaben verwendet werden, wobei ich letzteres empfehlen würde.

heisst "Umgebung stezen", dass ich /etc/init.d als Verzeichnis im Pfad aufführe,so dass alle Skripts daraus von überall her ausgeführt werden? Die zweite Variante verstehe ich nicht ganz. ich bin der Meinung, dass es keine Befehle hat, für die man einen Pfad aufschreiben muss. Bin der Meinung, dass es nur shell-Befhele drin hat. Und sowieso: müsste das nicht irgendwo gelogged sein, wenn Fehler auftreten?

borgiborgi

Avatar von borgiborgi

Anmeldungsdatum:
10. August 2009

Beiträge: 386

Wohnort: 3rd stone from the sun

Vielleicht postest Du mal Dein Script.

Und auch die Ausgabe von

ls -la /etc/init.d/dein_script

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Starte dein Script "in der Konsole, in der es funktioniert" mit

env -i  meinScript ...

Dann schaust du dir die Fehlermeldungen an.

borgiborgi

Avatar von borgiborgi

Anmeldungsdatum:
10. August 2009

Beiträge: 386

Wohnort: 3rd stone from the sun

lukpor schrieb:

heisst "Umgebung stezen", dass ich /etc/init.d als Verzeichnis im Pfad aufführe,so dass alle Skripts daraus von überall her ausgeführt werden? Die zweite Variante verstehe ich nicht ganz. ich bin der Meinung, dass es keine Befehle hat, für die man einen Pfad aufschreiben muss. Bin der Meinung, dass es nur shell-Befhele drin hat. Und sowieso: müsste das nicht irgendwo gelogged sein, wenn Fehler auftreten?

Umgebung setzten heisst, dass Du sicherstellen musst die richtigen Umgebungsvariablen, wie z.B. $PATH gesetzt hast. Du könntest also zu Beginn des Scripts ein

export PATH='/deine/Pfade'

setzen. Viel sauberer Programmierstil ist es jedoch, so wie adun schrieb, stets absolute Pfadangaben für Befehle in Scripten zu verwenden. Das hat insbesondere aus Sicherheitsüberlegungen enorme Vorteile. Zudem brauchst Du Dir dann über eine PATH-Variable (und ihre Reihenfolge!) keine Gedanken zu machen.

Ob Du wirklich nur Shell-Builtin-Befehle verwendest, verrät Dir 'type':

user@host:~$ type cd
cd is a shell builtin
user@host:~$ type rm
rm is /bin/rm

lukpor

(Themenstarter)

Anmeldungsdatum:
26. September 2010

Beiträge: 5

borgiborgi schrieb:

lukpor schrieb:

heisst "Umgebung stezen", dass ich /etc/init.d als Verzeichnis im Pfad aufführe,so dass alle Skripts daraus von überall her ausgeführt werden? Die zweite Variante verstehe ich nicht ganz. ich bin der Meinung, dass es keine Befehle hat, für die man einen Pfad aufschreiben muss. Bin der Meinung, dass es nur shell-Befhele drin hat. Und sowieso: müsste das nicht irgendwo gelogged sein, wenn Fehler auftreten?

Umgebung setzten heisst, dass Du sicherstellen musst die richtigen Umgebungsvariablen, wie z.B. $PATH gesetzt hast. Du könntest also zu Beginn des Scripts ein

export PATH='/deine/Pfade'

setzen. Viel sauberer Programmierstil ist es jedoch, so wie adun schrieb, stets absolute Pfadangaben für Befehle in Scripten zu verwenden. Das hat insbesondere aus Sicherheitsüberlegungen enorme Vorteile. Zudem brauchst Du Dir dann über eine PATH-Variable (und ihre Reihenfolge!) keine Gedanken zu machen.

Ob Du wirklich nur Shell-Builtin-Befehle verwendest, verrät Dir 'type':

user@host:~$ type cd
cd is a shell builtin
user@host:~$ type rm
rm is /bin/rm

Komme gerne auf dein Angebot von weiter oben zurück, das Skript zu posten. Habe alles versucht: die Pfade ausgeschrieben, die Umgebung eingelesen. Trotzdem startet das Skript nicht. Mit der Bash lässt es sich nach wie vor starten und stoppen. Vielleicht sieht jemand was. Sonst schreibe ich's dann halt um und lasse es in bestimmten Intervallen von Cron aufrufen, was mir aber weniger elegant scheint. Das Skript checkt übrigens in definierten Intervallen, ob bestimmte Rechner noch am Netz sind und fährt den Rechner runter, wenn dies nicht mehr der Fall ist.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          server-sleepd
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO
#
# Überwacht das LAN auf aktive Rechner und
# fährt den Server runter, wenn niemand mehr
# im LAN aktiv ist
#
# Ursprung: Reiko Kaps <rek@ct.de> 2009 
# an die eigenen Bedürfnisse adapiert 
# Wenn der Code etwas chaotisch daherkommt, geht dies 
# nur auf diese Adaptionen zurück......  
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games'
# Ping-Befehl mit Parametern
# hier: sendet zwei Anfragen
PING="/bin/ping -c 2"

# Liste der zu testenden Adressen
# nicht zu überprüfende lassen
# sich auskommentieren
HOSTS=`/bin/grep -v ^# <<!
#192.168.1.11
192.168.1.14
192.168.1.15
!`

# Interval in Seconds
INTERVAL=60
STARTVERZOEGERUNG=30

#CHECKLOCALUSER=true

# Dummy für den Zustand
ACTIVE=false
START=false

# shotdown- oder sleep-Befehl samt Parameter
# *BITTE anpassen* /bin/true ist zum testen gedacht!
#
 CMD="/sbin/shutdown -h now"
# CMD="/sbin/halt"
# CMD="/usr/sbin/pm-suspend"
# CMD="/usr/sbin/pm-powersave"
# CMD="/bin/true"

# 1 == an, '' == aus

#DEBUG=1
# Lockfile enthält Prozess-ID (PID)
BASENAME=`/usr/bin/basename $0`
LOCKFILE="/var/run/${BASENAME}.pid"

##
# überprüfe host-list
function checkhosts()
{

ACTIVE=false
for ADDR in ${HOSTS}
do
  ${PING} ${ADDR} > /dev/null
  if [ $? -eq 0 ]
   then
    echo $0": "${ADDR}" ist aktiv!"
    ACTIVE=true
    continue
   else
    echo $0": "${ADDR}" nicht aktiv!"
   fi
done

##
# ist ACTIVE noch 0, sind alle Rechner aus?
if [ "${ACTIVE}" = "false" ]
then
 # schaltet Rechner ab, falls keine lokalen/SSH-Nutzer da sind
  echo $0": keine LAN-Rechner aktiv, schaltet Server aus"
 /usr/bin/logger -t $0 "keine LAN-Rechner aktiv, schaltet Server ab..."
         abschalten
else
 echo $0": Tue nichts, LAN-Rechner aktiv!"
fi

} 

##
# Schaltet Rechner aus, legt ihn schlafen
function abschalten()
{
#  [ ${DEBUG} ] && echo "Führe Kommando $CMD aus ..."
  /usr/bin/logger -t $0 "Schalte Rechner mit Kommando ${CMD} aus."
  ${CMD} 
}

## 
# Überprüfe auf lokal oder per SSH angemeldete Nutzer
# berücksichtigt auch Screen-Sitzungen!
function localUsers()
{
  COUNT=`/usr/bin/w -h | /bin/sed '/^\s*$/d' | /usr/bin/wc -l`
  echo "$0: Lokale Benutzer: $COUNT "
  return ${COUNT}
}

##
# Hauptprogramm

# Dauerschleife bis Strg-C, kill, killall ...

function runcheck()
{
 echo $$ > ${LOCKFILE}
 trap "/bin/rm -f ${LOCKFILE}; exit" INT TERM EXIT
 echo "name des programms ist $0"
 echo 'komme gleich zum start'
 /bin/sleep $STARTVERZOEGERUNG
 echo 'gestartet'
 while true
 do
 
  if [ "${CHECKLOCALUSER}" = "true" ]
   then
   localUsers
   if [ $? -eq 0 ]
    then checkhosts 
   else /usr/bin/logger -t $0 " $? lokale Nutzer angemeldet"
    echo 'lokale user angemeldet: stop'
   fi
  else
   checkhosts
  fi

 echo 'pause'
 /bin/sleep $INTERVAL
 done
}

function stopcheck()
{ 
        if [ -e ${LOCKFILE} ]
        then
          CPID=`/bin/cat ${LOCKFILE}`
          echo -ne "Stopping $0 with PID $CPID "
          # beenden mit SIGTERM,
          # warte bis PID-File entfernt ist
          while [ -e ${LOCKFILE} ]
          do
             echo -ne "."
             kill ${CPID}
             /bin/sleep 2
          done
          echo "[done]"
    
        else
          echo "$0 is not running."
          exit
        fi        
}

case "$1" in 
run)
 runcheck
;;
stop)
 stopcheck
;;
start)
runcheck 
;;
restart)
stopcheck
;;

esac

lukpor

(Themenstarter)

Anmeldungsdatum:
26. September 2010

Beiträge: 5

lukpor schrieb:

borgiborgi schrieb:

lukpor schrieb:

heisst "Umgebung stezen", dass ich /etc/init.d als Verzeichnis im Pfad aufführe,so dass alle Skripts daraus von überall her ausgeführt werden? Die zweite Variante verstehe ich nicht ganz. ich bin der Meinung, dass es keine Befehle hat, für die man einen Pfad aufschreiben muss. Bin der Meinung, dass es nur shell-Befhele drin hat. Und sowieso: müsste das nicht irgendwo gelogged sein, wenn Fehler auftreten?

Umgebung setzten heisst, dass Du sicherstellen musst die richtigen Umgebungsvariablen, wie z.B. $PATH gesetzt hast. Du könntest also zu Beginn des Scripts ein

export PATH='/deine/Pfade'

setzen. Viel sauberer Programmierstil ist es jedoch, so wie adun schrieb, stets absolute Pfadangaben für Befehle in Scripten zu verwenden. Das hat insbesondere aus Sicherheitsüberlegungen enorme Vorteile. Zudem brauchst Du Dir dann über eine PATH-Variable (und ihre Reihenfolge!) keine Gedanken zu machen.

Ob Du wirklich nur Shell-Builtin-Befehle verwendest, verrät Dir 'type':

user@host:~$ type cd
cd is a shell builtin
user@host:~$ type rm
rm is /bin/rm

Komme gerne auf dein Angebot von weiter oben zurück, das Skript zu posten. Habe alles versucht: die Pfade ausgeschrieben, die Umgebung eingelesen. Trotzdem startet das Skript nicht. Mit der Bash lässt es sich nach wie vor starten und stoppen. Vielleicht sieht jemand was. Sonst schreibe ich's dann halt um und lasse es in bestimmten Intervallen von Cron aufrufen, was mir aber weniger elegant scheint. Das Skript checkt übrigens in definierten Intervallen, ob bestimmte Rechner noch am Netz sind und fährt den Rechner runter, wenn dies nicht mehr der Fall ist.

#! /bin/sh
### BEGIN INIT INFO
# Provides:          server-sleepd
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: Example initscript
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO
#
# Überwacht das LAN auf aktive Rechner und
# fährt den Server runter, wenn niemand mehr
# im LAN aktiv ist
#
# Ursprung: Reiko Kaps <rek@ct.de> 2009 
# an die eigenen Bedürfnisse adapiert 
# Wenn der Code etwas chaotisch daherkommt, geht dies 
# nur auf diese Adaptionen zurück......  
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games'
# Ping-Befehl mit Parametern
# hier: sendet zwei Anfragen
PING="/bin/ping -c 2"

# Liste der zu testenden Adressen
# nicht zu überprüfende lassen
# sich auskommentieren
HOSTS=`/bin/grep -v ^# <<!
#192.168.1.11
192.168.1.14
192.168.1.15
!`

# Interval in Seconds
INTERVAL=60
STARTVERZOEGERUNG=30

#CHECKLOCALUSER=true

# Dummy für den Zustand
ACTIVE=false
START=false

# shotdown- oder sleep-Befehl samt Parameter
# *BITTE anpassen* /bin/true ist zum testen gedacht!
#
 CMD="/sbin/shutdown -h now"
# CMD="/sbin/halt"
# CMD="/usr/sbin/pm-suspend"
# CMD="/usr/sbin/pm-powersave"
# CMD="/bin/true"

# 1 == an, '' == aus

#DEBUG=1
# Lockfile enthält Prozess-ID (PID)
BASENAME=`/usr/bin/basename $0`
LOCKFILE="/var/run/${BASENAME}.pid"

##
# überprüfe host-list
function checkhosts()
{

ACTIVE=false
for ADDR in ${HOSTS}
do
  ${PING} ${ADDR} > /dev/null
  if [ $? -eq 0 ]
   then
    echo $0": "${ADDR}" ist aktiv!"
    ACTIVE=true
    continue
   else
    echo $0": "${ADDR}" nicht aktiv!"
   fi
done

##
# ist ACTIVE noch 0, sind alle Rechner aus?
if [ "${ACTIVE}" = "false" ]
then
 # schaltet Rechner ab, falls keine lokalen/SSH-Nutzer da sind
  echo $0": keine LAN-Rechner aktiv, schaltet Server aus"
 /usr/bin/logger -t $0 "keine LAN-Rechner aktiv, schaltet Server ab..."
         abschalten
else
 echo $0": Tue nichts, LAN-Rechner aktiv!"
fi

} 

##
# Schaltet Rechner aus, legt ihn schlafen
function abschalten()
{
#  [ ${DEBUG} ] && echo "Führe Kommando $CMD aus ..."
  /usr/bin/logger -t $0 "Schalte Rechner mit Kommando ${CMD} aus."
  ${CMD} 
}

## 
# Überprüfe auf lokal oder per SSH angemeldete Nutzer
# berücksichtigt auch Screen-Sitzungen!
function localUsers()
{
  COUNT=`/usr/bin/w -h | /bin/sed '/^\s*$/d' | /usr/bin/wc -l`
  echo "$0: Lokale Benutzer: $COUNT "
  return ${COUNT}
}

##
# Hauptprogramm

# Dauerschleife bis Strg-C, kill, killall ...

function runcheck()
{
 echo $$ > ${LOCKFILE}
 trap "/bin/rm -f ${LOCKFILE}; exit" INT TERM EXIT
 echo "name des programms ist $0"
 echo 'komme gleich zum start'
 /bin/sleep $STARTVERZOEGERUNG
 echo 'gestartet'
 while true
 do
 
  if [ "${CHECKLOCALUSER}" = "true" ]
   then
   localUsers
   if [ $? -eq 0 ]
    then checkhosts 
   else /usr/bin/logger -t $0 " $? lokale Nutzer angemeldet"
    echo 'lokale user angemeldet: stop'
   fi
  else
   checkhosts
  fi

 echo 'pause'
 /bin/sleep $INTERVAL
 done
}

function stopcheck()
{ 
        if [ -e ${LOCKFILE} ]
        then
          CPID=`/bin/cat ${LOCKFILE}`
          echo -ne "Stopping $0 with PID $CPID "
          # beenden mit SIGTERM,
          # warte bis PID-File entfernt ist
          while [ -e ${LOCKFILE} ]
          do
             echo -ne "."
             kill ${CPID}
             /bin/sleep 2
          done
          echo "[done]"
    
        else
          echo "$0 is not running."
          exit
        fi        
}

case "$1" in 
run)
 runcheck
;;
stop)
 stopcheck
;;
start)
runcheck 
;;
restart)
stopcheck
;;

esac

Starte das Skript nun mit cron. Problem umgangen...

Antworten |