Skrypt killujący procesy

Potrzebujesz pomocy z C, C++, perl, python, itp.
Fredx121
Posty: 22
Rejestracja: 11 września 2018, 13:11

Skrypt killujący procesy

Post autor: Fredx121 »

Witajcie. Potrzebuję pomocy ze skryptem startującym/stopującym transcoder shoutcast. Chodzi dokładnie o to, że gdy chcę zatrzymać transcoder wpisujac :
./pilot stop WYSKAKUJE KOMUNIKAT :

Kod: Zaznacz cały

root@185a140b121c108:/home/serwery/club# ./pilot stop
./pilot: 43: ./pilot: [[: not found
Pilot 'club' nie jest odpalony!
Odpowiada za to ta linia:

Kod: Zaznacz cały

   if [[ `ps ax | grep $PID | grep -v grep` ]]
Cały skrypt :

Kod: Zaznacz cały

#! /bin/sh
#
# Start the PILOT for shoutcast!!!.
#
# by Aesthetic

USR=`pwd | sed 's![a-zA-Z0-9_]*/!!g'`
PID=`cat $USR.trans.pid`
DIR=`pwd`
DIRP=/home/serwery/$USR/
DIR_MP3=${DIRP}mp3/
DIR_CONF=${DIRP}conf/
CALFILE=calendar.xml
DJFILE=dj.conf
PLS=pls.tmp
DIR_PLAYLISTS=${DIRP}playlists/
APP=sc_trans
IEPARAMS=sc_pilot.ie
TMPPARAMS=sc_pilot.tmp
PARAMS=sc_pilot.conf
USRBIN=/usr/bin/

case "$1" in
 start)
   if [[ `ps ax | grep $PID | grep -v grep` ]]
       then
       echo "Pilot dla usera '$USR' juz jest odpalony!"
     else
       echo "Generuje plik konfiguracyjny!"
       $0 playlists
       cat $IEPARAMS $TMPPARAMS $DIR_CONF$DJFILE $PLS > $PARAMS
       echo "calendarfile=$DIR_CONF$CALFILE" >> $PARAMS
       echo "Plik konfiguracyjny wygenerowany!"
       echo "Odpalam pilota dla usera '$USR'!";
       $0 update
       cd $DIR
       ./$APP $PARAMS > /dev/null & echo $! > $USR.trans.pid
       echo "Pilot odpalony!"
   fi
   ;;

 stop)
   if [[ `ps ax | grep $PID | grep -v grep` ]]
       then
       echo "Zatrzymuje pilota '$USR'!"
       kill -s KILL $PID
       echo "Pilot wylaczony!"
    else
       echo "Pilot '$USR' nie jest odpalony!"
   fi
   ;;

 reload)
       kill -s USR1 $PID
       echo "Laduje nowa playliste do pilota!"
   ;;

 next)
       kill -s WINCH $PID
       echo "Skacze do nastepnego kawalku!"
   ;;

 update)
   echo "Generuje refresh glownej playlisty!"
   #${USRBIN}find . -ctime -4 > bla.txt
   ${USRBIN}find $DIR_MP3 -type f -name "*.mp3" | ${USRBIN}sort | sed -e 's!\[!\\\[!g' -e 's!\]!\\\]!g' -e '$s/$/\n\n###!EOF/' > play_pilot.lst
   sleep 2
   echo "Playlista gotowa!"
   ;;

 test)
   echo "test"
   ${USRBIN}find -version 
   echo "test2"
   ;;

 playlists)
   echo "Dodaje playlisty z folderu playlists!"
   ${USRBIN}find $DIR_PLAYLISTS -type f -name "*.lst" | sed '

		h #save to hold space
		s/.*\//=/ #remove path but add '=' instead
		s/.lst// #remove extension from every line
		s/^/playlistfilename_/ #add string to beginning of line
		= #print line number 
		p #print stripped filename
		= #print line number
		x #print string in hold space
		s/.*\//=&/ #add '=' before filepath
		s/^/playlistfilepath_/ #add string to beginning of line

	' | sed -e 'N;s/\n//' \
						-e 's!^\([0-9+]\)\([a-zA-Z0-9_-]*\)=!\2\1=!' \
						-e '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' | sed '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' > $PLS
	 rm ${PLS}x

   sleep 1
   echo "Wpisy gotowe!"
   ;;

 restart)
   $0 stop
   $0 start
   ;;

 usage)
   sudo quota $USR | tail -n 1
   ;;

 status)
    # check if servers are running
    if [[ `ps ax | grep $PID | grep -v grep` ]]
      then
      echo "UP"
    else
      echo "DOWN"
    fi
    ;;

 *)
   echo "Usage: $0 {start|stop|restart|update|status|reload|next|usage|playlists}"
   exit 1
   ;;
esac

exit 0
Dzięki za pomoc.
Awatar użytkownika
lizard
Beginner
Posty: 287
Rejestracja: 08 lutego 2016, 18:47

Re: Skrypt killujący procesy

Post autor: lizard »

Używasz składni Basha w interpreterze powłoki zgodnej z POSIX-em - w Debianie jest to Dash. Zmień pierwszą linię "#!/bin/sh" na "#!/bin/bash".

Poza tym zamiast:

Kod: Zaznacz cały

USR=`pwd | sed 's![a-zA-Z0-9_]*/!!g'`
PID=`cat $USR.trans.pid`
DIR=`pwd`
użyj (szybciej):

Kod: Zaznacz cały

USR="${PWD##*/}"
P=`<$USR.trans.pid`
DIR="${PWD}"
Skąd wiesz, że skrypt uruchomi się w konkretnym katalogu? Bezpieczniej będzie, gdy zastosujesz ścieżki bezwzględne lub przypiszesz taką do zmiennej, a tę będziesz umieszczać przed ścieżkami względnymi, np:

Kod: Zaznacz cały

BASEDIR='/home/user'
PID=`<${BASEDIR}/$USR.trans.pid`
Po co od razu strzał grubej rury: kill -s KILL. Na początek zwykły SIGTERM, poczekać sekundę lub dwie i jeżeli proces nadal istnieje, to puścić SIGKILL.

[[ `ps ax | grep $PID | grep -v grep` ]] możesz zastąpić [[ -d /proc/$PID ]] (szybciej).

Zmienna USRBIN jest niepotrzebna. Wystarczy na początku skryptu ustawić własną wartość zmiennej PATH.
Awatar użytkownika
dedito
Moderator
Posty: 3512
Rejestracja: 18 listopada 2013, 21:07
Lokalizacja: Gliwice

Re: Skrypt killujący procesy

Post autor: dedito »

W warunku prościej będzie użyć

Kod: Zaznacz cały

kill -0 $PID
lub jak sugeruje kolega lizard.
Fredx121
Posty: 22
Rejestracja: 11 września 2018, 13:11

Re: Skrypt killujący procesy

Post autor: Fredx121 »

Cieszę się, że zainteresowaliście się moim problemem.
Otóż w pewnym stopniu zastosowałem się do waszych wskazówek i proponowanych zmian, i mój kod wyglada tak:

Kod: Zaznacz cały

#!/bin/bash
#
# Start the PILOT for shoutcast!!!.
#
# by Aesthetic

USR="${PWD##*/}"
P=`<$USR.trans.pid`
DIR="${PWD}"
DIRP=/home/serwery/$USR/
DIR_MP3=${DIRP}mp3/
DIR_CONF=${DIRP}conf/
CALFILE=calendar.xml
DJFILE=dj.conf
PLS=pls.tmp
DIR_PLAYLISTS=${DIRP}playlists/
APP=sc_trans
IEPARAMS=sc_pilot.ie
TMPPARAMS=sc_pilot.tmp
PARAMS=sc_pilot.conf
USRBIN=/usr/bin/

case "$1" in
 start)
   if [[ -d /proc/$PID ]]
       then
       echo "Pilot dla usera '$USR' juz jest odpalony!"
     else
       echo "Generuje plik konfiguracyjny!"
       $0 playlists
       cat $IEPARAMS $TMPPARAMS $DIR_CONF$DJFILE $PLS > $PARAMS
       echo "calendarfile=$DIR_CONF$CALFILE" >> $PARAMS
       echo "Plik konfiguracyjny wygenerowany!"
       echo "Odpalam pilota dla usera '$USR'!";
       $0 update
       cd $DIR
       ./$APP $PARAMS > /dev/null & echo $! > $USR.trans.pid
       echo "Pilot odpalony!"
   fi
   ;;

 stop)
   if [[ -d /proc/$PID ]]
       then
       echo "Zatrzymuje pilota '$USR'!"
       kill -0 $PID
       echo "Pilot wylaczony!"
    else
       echo "Pilot '$USR' nie jest odpalony!"
   fi
   ;;

 reload)
       kill -s USR1 $PID
       echo "Laduje nowa playliste do pilota!"
   ;;

 next)
       kill -s WINCH $PID
       echo "Skacze do nastepnego kawalku!"
   ;;

 update)
   echo "Generuje refresh glownej playlisty!"
   #${USRBIN}find . -ctime -4 > bla.txt
   ${USRBIN}find $DIR_MP3 -type f -name "*.mp3" | ${USRBIN}sort | sed -e 's!\[!\\\[!g' -e 's!\]!\\\]!g' -e '$s/$/\n\n###!EOF/' > play_pilot.lst
   sleep 2
   echo "Playlista gotowa!"
   ;;

 test)
   echo "test"
   ${USRBIN}find -version 
   echo "test2"
   ;;

 playlists)
   echo "Dodaje playlisty z folderu playlists!"
   ${USRBIN}find $DIR_PLAYLISTS -type f -name "*.lst" | sed '

		h #save to hold space
		s/.*\//=/ #remove path but add '=' instead
		s/.lst// #remove extension from every line
		s/^/playlistfilename_/ #add string to beginning of line
		= #print line number 
		p #print stripped filename
		= #print line number
		x #print string in hold space
		s/.*\//=&/ #add '=' before filepath
		s/^/playlistfilepath_/ #add string to beginning of line

	' | sed -e 'N;s/\n//' \
						-e 's!^\([0-9+]\)\([a-zA-Z0-9_-]*\)=!\2\1=!' \
						-e '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' | sed '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' > $PLS
	 rm ${PLS}x

   sleep 1
   echo "Wpisy gotowe!"
   ;;

 restart)
   $0 stop
   $0 start
   ;;

 usage)
   sudo quota $USR | tail -n 1
   ;;

 status)
    # check if servers are running
    if [[ `ps ax | grep $PID | grep -v grep` ]]
      then
      echo "UP"
    else
      echo "DOWN"
    fi
    ;;

 *)
   echo "Usage: $0 {start|stop|restart|update|status|reload|next|usage|playlists}"
   exit 1
   ;;
esac

exit 0

Teraz po wpisaniu komendy ./pilot stop, mam komunikat :

Kod: Zaznacz cały

root@185a140b121c108:/home/serwery/club# ./pilot stop
Zatrzymuje pilota 'club'!
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Pilot wylaczony!
root@185a140b121c108:/home/serwery/club#
Przypuszczam, że nie wie co killować, i mimo komentarza o sukcesie pilot nadal działa, nie wyłącza się.
Awatar użytkownika
lizard
Beginner
Posty: 287
Rejestracja: 08 lutego 2016, 18:47

Re: Skrypt killujący procesy

Post autor: lizard »

Zgadza się. Zamiast P=`<$USR.trans.pid` powinno być PID=`<$USR.trans.pid`. Z lenistwa wpisałem w terminalu jednoliterową nazwę zmiennej, a później zapomniałem dostosować do Twojego skryptu.

To bardzo dobry przykład na to, aby rozumieć co się przeklepuje i nie pozwolić na wpuszczenie siebie w maliny. ;)
Fredx121
Posty: 22
Rejestracja: 11 września 2018, 13:11

Re: Skrypt killujący procesy

Post autor: Fredx121 »

Tak jak mówisz, dobry przykład .! Wklepałem na oślep i puściłem bez analizy masz racje.

Ale chcę Ci bardzo podziękować bo rozwiązałeś mój problem z tym skryptem.

Bardzo Ci dziękuję ;-)
Awatar użytkownika
LordRuthwen
Moderator
Posty: 2302
Rejestracja: 18 września 2009, 21:45
Lokalizacja: klikash?

Re: Skrypt killujący procesy

Post autor: LordRuthwen »

:)
A teraz pomyśl co by było gdybyś przekleił rm-fr / ;)
Oznacz temat jako rozwiązany.
Fredx121
Posty: 22
Rejestracja: 11 września 2018, 13:11

Re: Skrypt killujący procesy

Post autor: Fredx121 »

Właśnie miałem zamykać temat, gdy przerzuciłem skrypt do innego katalogu tzw. 2 serwera, i podczas uruchamiania go mam błąd :

Kod: Zaznacz cały

root@185a140b121c108:/home/serwery/disco# ./pilot start
./pilot: line 8: disco.trans.pid: No such file or directory
Pilot dla usera 'disco' juz jest odpalony!
Cały skrypt:

Kod: Zaznacz cały

#!/bin/bash
#
# Start the PILOT for shoutcast!!!.
#
# by Aesthetic

USR="${PWD##*/}"
PID=`<$USR.trans.pid`
DIR="${PWD}"
DIRP=/home/serwery/$USR/
DIR_MP3=${DIRP}mp3/
DIR_CONF=${DIRP}conf/
CALFILE=calendar.xml
DJFILE=dj.conf
PLS=pls.tmp
DIR_PLAYLISTS=${DIRP}playlists/
APP=sc_trans
IEPARAMS=sc_pilot.ie
TMPPARAMS=sc_pilot.tmp
PARAMS=sc_pilot.conf
USRBIN=/usr/bin/

case "$1" in
 start)
   if [[ -d /proc/$PID ]]
       then
       echo "Pilot dla usera '$USR' juz jest odpalony!"
     else
       echo "Generuje plik konfiguracyjny!"
       $0 playlists
       cat $IEPARAMS $TMPPARAMS $DIR_CONF$DJFILE $PLS > $PARAMS
       echo "calendarfile=$DIR_CONF$CALFILE" >> $PARAMS
       echo "Plik konfiguracyjny wygenerowany!"
       echo "Odpalam pilota dla usera '$USR'!";
       $0 update
       cd $DIR
       ./$APP $PARAMS > /dev/null & echo $! > $USR.trans.pid
       echo "Pilot odpalony!"
   fi
   ;;

 stop)
   if [[ -d /proc/$PID ]]
       then
       echo "Zatrzymuje pilota '$USR'!"
        kill -s KILL $PID
       echo "Pilot wylaczony!"
    else
       echo "Pilot '$USR' nie jest odpalony!"
   fi
   ;;

 reload)
       kill -s USR1 $PID
       echo "Laduje nowa playliste do pilota!"
   ;;

 next)
       kill -s WINCH $PID
       echo "Skacze do nastepnego kawalku!"
   ;;

 update)
   echo "Generuje refresh glownej playlisty!"
   #${USRBIN}find . -ctime -4 > bla.txt
   ${USRBIN}find $DIR_MP3 -type f -name "*.mp3" | ${USRBIN}sort | sed -e 's!\[!\\\[!g' -e 's!\]!\\\]!g' -e '$s/$/\n\n###!EOF/' > play_pilot.lst
   sleep 2
   echo "Playlista gotowa!"
   ;;

 test)
   echo "test"
   ${USRBIN}find -version 
   echo "test2"
   ;;

 playlists)
   echo "Dodaje playlisty z folderu playlists!"
   ${USRBIN}find $DIR_PLAYLISTS -type f -name "*.lst" | sed '

		h #save to hold space
		s/.*\//=/ #remove path but add '=' instead
		s/.lst// #remove extension from every line
		s/^/playlistfilename_/ #add string to beginning of line
		= #print line number 
		p #print stripped filename
		= #print line number
		x #print string in hold space
		s/.*\//=&/ #add '=' before filepath
		s/^/playlistfilepath_/ #add string to beginning of line

	' | sed -e 'N;s/\n//' \
						-e 's!^\([0-9+]\)\([a-zA-Z0-9_-]*\)=!\2\1=!' \
						-e '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' | sed '$s/\([a-zA-Z_-]*\)[0-9][0-9]*/\10/' > $PLS
	 ${USRBIN}tail -1 $PLS > ${PLS}x
	 cat $PLS >> ${PLS}x
	 cat ${PLS}x | sed '$d' > $PLS
	 rm ${PLS}x

   sleep 1
   echo "Wpisy gotowe!"
   ;;

 restart)
   $0 stop
   $0 start
   ;;

 usage)
   sudo quota $USR | tail -n 1
   ;;

 status)
    # check if servers are running
    if [[ `ps ax | grep $PID | grep -v grep` ]]
      then
      echo "UP"
    else
      echo "DOWN"
    fi
    ;;

 *)
   echo "Usage: $0 {start|stop|restart|update|status|reload|next|usage|playlists}"
   exit 1
   ;;
esac

exit 0

Na pierwszym serwerze działa bez zarzutów, jak sie domyślam skrypt nie rozpoznaje 2 katalogu, w którym ma uruchomić proces? Kombinowałem ze zmianą scieżki, niewiele to pomogło. Szczerze, to noga w tym ze mnie.
Awatar użytkownika
lizard
Beginner
Posty: 287
Rejestracja: 08 lutego 2016, 18:47

Re: Skrypt killujący procesy

Post autor: lizard »

Skrypt nie znajduje pliku w linii:

Kod: Zaznacz cały

PID=`<$USR.trans.pid`
Sądząc po nazwie tego pliku, jak i pierwotnej wersji Twojego skryptu, to przechowywany jest w nim PID procesu. Jeżeli pilot nie jest uruchomiony, to nie ma pliku $PID.trans.pid. W takim razie zamiast powyższej linii umieść w skrypcie:

Kod: Zaznacz cały

if [[ -f $USR.trans.pid ]]; then
  PID=`<$USR.trans.pid`
fi
A w dalszej części:

Kod: Zaznacz cały

  start)
    if [[ -f $USR.trans.pid ]]; then
      echo "Pilot dla usera '$USR' juz jest odpalony!"
    else

# ... ciach ...

  stop)
    if [[ -d /proc/$PID ]]; then
      echo "Zatrzymuje pilota '$USR'!"
      kill -s KILL $PID
      rm -f $PID.trans.pid
      echo "Pilot wylaczony!"
Wnioskuję, że linia kill -s KILL $PID powoduje, że plik $PID.trans.pid nie jest usuwany przy wyłączaniu. Zamień ją na kill -s SIGTERM $PID, a najprawdopodobniej linia rm -f $PID.trans.pid nie będzie potrzebna.
Fredx121
Posty: 22
Rejestracja: 11 września 2018, 13:11

Re: Skrypt killujący procesy

Post autor: Fredx121 »

Teraz wygląda to w taki sposób, że skrypt uruchamia proces, oraz podczas gdy chcę proces killować za pomocą komendy ./pilot stop, wszystko działa... ale przy ponownym uruchomieniu procesu komendą ./pilot start, wywala komunikat :

Kod: Zaznacz cały

root@185a140b121c108:/home/serwery/disco# ./pilot start
Pilot dla usera 'disco' juz jest odpalony!
Zauważyłem, że skrypt killuje proces ale nie usuwa pliku 'disco.trans.pid'
ODPOWIEDZ