Модераторы: powerfox, ZeeLax
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Демон-скрипт под SUSE 
V
    Опции темы
neiron
Дата 2.9.2008, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



Здравствуйте. 
Стала следующая проблема - необходимо запустить прогу в виде демона. 
Сам в этом не сильно соображаю, но нашёл в сети занимательный скрипт:

Код

#!/bin/sh
#
# A SUSE Linux start/stop script for Java daemons.
#
# Home page: http://www.source-code.biz
# License:   GNU/LGPL (http://www.gnu.org/licenses/lgpl.html)
# Copyright 2006 Christian d'Heureuse, Inventec Informatik AG, Switzerland.
#
# History:
# 2006-06-27 Christian d'Heureuse: Script created.
# 2006-07-02 chdh: Minor improvements.
# 2006-07-10 chdh: Changes for SUSE 10.0.

### BEGIN INIT INFO
# Provides:                   javaDaemonTest
# Required-Start:             $network $local_fs $remote_fs
# X-UnitedLinux-Should-Start: $named sendmail
# Required-Stop:              $network $local_fs $remote_fs
# X-UnitedLinux-Should-Stop:  $named sendmail
# Default-Start:              3 5
# Default-Stop:               0 1 2 6
# Short-Description:          JavaDaemonTest
# Description:                A Java daemon for testing.
### END INIT INFO

. /etc/rc.status                                           # load start/stop script "rc" definitions
if [ -z "$JAVA_HOME" ]; then                               # if JAVA_HOME is undefined
   if [ -f /usr/share/java-utils/java-functions ]; then
      . /usr/share/java-utils/java-functions; set_jvm      # JPackage standard method to set JAVA_HOME
    elif [ -n "$(type -t setJava)" ]; then
      . setJava ""; fi                                     # old SUSE method to set JAVA_HOME
   if [ -z "$JAVA_HOME" ]; then echo Unable to set JAVA_HOME environment variable; exit 1; fi
   fi

scriptFile=$(readlink -fn $(type -p $0))                   # the absolute, dereferenced path of this script file
scriptDir=$(dirname $scriptFile)                           # absolute path of the script directory
applDir="$scriptDir"                                       # home directory of the service application
serviceName="JavaDaemonTest"                               # service name
serviceNameLo="javaDaemonTest"                             # service name with the first letter in lowercase
serviceUser="jdmntest"                                     # OS user name for the service
serviceUserHome="$applDir"                                 # home directory of the service user
serviceGroup="jdmntest"                                    # OS group name for the service
serviceLogFile="/var/log/$serviceNameLo.log"               # log file for StdOut/StdErr
maxShutdownTime=15                                         # maximum number of seconds to wait for the daemon to terminate normally
pidFile="/var/run/$serviceNameLo.pid"                      # name of PID file (PID = process ID number)
javaCommand="java"                                         # name of the Java launcher without the path
javaExe="$JAVA_HOME/bin/$javaCommand"                      # file name of the Java application launcher executable
javaArgs="JavaDaemonTest"                                  # arguments for Java launcher
javaCommandLine="$javaExe $javaArgs"                       # command line to start the Java service application
javaCommandLineKeyword="JavaDaemonTest"                    # a keyword that occurs on the commandline, used to detect an already running service process and to distinguish it from others
rcFileBaseName="rc$serviceNameLo"                          # basename of the "rc" symlink file for this script
rcFileName="/usr/local/sbin/$rcFileBaseName"               # full path of the "rc" symlink file for this script
etcInitDFile="/etc/init.d/$serviceNameLo"                  # symlink to this script from /etc/init.d

# Makes the file $1 writable by the group $serviceGroup.
function makeFileWritable {
   local filename="$1"
   touch $filename || return 1
   chgrp $serviceGroup $filename || return 1
   chmod g+w $filename || return 1
   return 0; }

# Returns 0 if the process with PID $1 is running.
function checkProcessIsRunning {
   local pid="$1"
   if [ -z "$pid" -o "$pid" == " " ]; then return 1; fi
   if [ ! -e /proc/$pid ]; then return 1; fi
   return 0; }

# Returns 0 if the process with PID $1 is our Java service process.
function checkProcessIsOurService {
   local pid="$1"
   if [ "$(ps -p $pid --no-headers -o comm)" != "$javaCommand" ]; then return 1; fi
   grep -q --binary -F "$javaCommandLineKeyword" /proc/$pid/cmdline
   if [ $? -ne 0 ]; then return 1; fi
   return 0; }

# Returns 0 when the service is running and sets the variable $pid to the PID.
function getServicePID {
   if [ ! -f $pidFile ]; then return 1; fi
   pid="$(<$pidFile)"
   checkProcessIsRunning $pid || return 1
   checkProcessIsOurService $pid || return 1
   return 0; }

function startServiceProcess {
   cd $applDir || return 1
   rm -f $pidFile
   makeFileWritable $pidFile || return 1
   makeFileWritable $serviceLogFile || return 1
   cmd="nohup $javaCommandLine >>$serviceLogFile 2>&1 & echo \$! >$pidFile"
   sudo -u $serviceUser $SHELL -c "$cmd" || return 1
   sleep 0.1
   pid="$(<$pidFile)"
   if checkProcessIsRunning $pid; then :; else
      echo -ne "\n$serviceName start failed, see logfile."
      return 1
      fi
   return 0; }

function stopServiceProcess {
   kill $pid || return 1
   for ((i=0; i<maxShutdownTime*10; i++)); do
      checkProcessIsRunning $pid
      if [ $? -ne 0 ]; then
         rm -f $pidFile
         return 0
         fi
      sleep 0.1
      done
   echo -e "\n$serviceName did not terminate within $maxShutdownTime seconds, sending SIGKILL..."
   kill -s KILL $pid || return 1
   local killWaitTime=15
   for ((i=0; i<killWaitTime*10; i++)); do
      checkProcessIsRunning $pid
      if [ $? -ne 0 ]; then
         rm -f $pidFile
         return 0
         fi
      sleep 0.1
      done
   echo "Error: $serviceName could not be stopped within $maxShutdownTime+$killWaitTime seconds!"
   return 1; }

function runInConsoleMode {
   getServicePID
   if [ $? -eq 0 ]; then echo "$serviceName is already running"; return 1; fi
   cd $applDir || return 1
   sudo -u $serviceUser $javaCommandLine || return 1
   if [ $? -eq 0 ]; then return 1; fi
   return 0; }

function startService {
   getServicePID
   if [ $? -eq 0 ]; then echo -n "$serviceName is already running"; rc_failed 0; rc_status -v; return 0; fi
   echo -n "Starting $serviceName   "
   startServiceProcess
   if [ $? -ne 0 ]; then rc_failed 1; rc_status -v; return 1; fi
   rc_failed 0
   rc_status -v
   return 0; }

function stopService {
   getServicePID
   if [ $? -ne 0 ]; then echo -n "$serviceName is not running"; rc_failed 0; rc_status -v; return 0; fi
   echo -n "Stopping $serviceName   "
   stopServiceProcess
   if [ $? -ne 0 ]; then rc_failed 1; rc_status -v; return 1; fi
   rc_failed 0
   rc_status -v
   return 0; }

function checkServiceStatus {
   echo -n "Checking for $serviceName:   "
   if getServicePID; then
      rc_failed 0
    else
      rc_failed 3
      fi
   rc_status -v
   return 0; }

function installService {
   getent group $serviceGroup >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating group $serviceGroup
      groupadd -r $serviceGroup || return 1
      fi
   id -u $serviceUser >/dev/null 2>&1
   if [ $? -ne 0 ]; then
      echo Creating user $serviceUser
      useradd -r -c "user for $serviceName service" -g $serviceGroup -G users -d $serviceUserHome $serviceUser
      fi
   ln -s $scriptFile $rcFileName || return 1
   ln -s $scriptFile $etcInitDFile || return 1
   insserv $serviceNameLo || return 1
   echo $serviceName installed.
   echo You may now use $rcFileBaseName to call this script.
   return 0; }

function uninstallService {
   insserv -r $serviceNameLo || return 1
   rm -f $rcFileName
   rm -f $etcInitDFile
   echo $serviceName uninstalled.
   return 0; }

function main {
   rc_reset
   case "$1" in
      console)                                             # runs the Java program in console mode
         runInConsoleMode
         ;;
      start)                                               # starts the Java program as a Linux service
         startService
         ;;
      stop)                                                # stops the Java program service
         stopService
         ;;
      restart)                                             # stops and restarts the service
         stopService && startService
         ;;
      status)                                              # displays the service status
         checkServiceStatus
         ;;
      install)                                             # installs the service in the OS
         installService
         ;;
      uninstall)                                           # uninstalls the service in the OS
         uninstallService
         ;;
      *)
         echo "Usage: $0 {console|start|stop|restart|status|install|uninstall}"
         exit 1
         ;;
      esac
   rc_exit; }

main $1


Запустил я его с прилагающимся .java скриптом. Всё работает - стартует, стопится, статус проверяется прекрасно. Отлично.

Однако, мне нужно запустить готовый .jar файлик. 
Как я понадеялся, для этого только лишь командную строку изменить надо было. 
В итоге инициализацию констант поменял вот так:

Код

scriptFile=$(readlink -fn $(type -p $0))                   # the absolute, dereferenced path of this script file
scriptDir=$(dirname $scriptFile)                           # absolute path of the script directory
applDir="$scriptDir"                                       # home directory of the service application
serviceName="JavaWriterTest"                               # service name
serviceNameLo="javaWriterTest"                             # service name with the first letter in lowercase
serviceUser="root"                                     # OS user name for the service
serviceUserHome="/root"                                 # home directory of the service user
serviceGroup="root"                                    # OS group name for the service
serviceLogFile="/var/log/$serviceNameLo.log"               # log file for StdOut/StdErr
maxShutdownTime=15                                         # maximum number of seconds to wait for the daemon to terminate normally
pidFile="/var/run/$serviceNameLo.pid"                      # name of PID file (PID = process ID number)
javaCommand="java"                                         # name of the Java launcher without the path
javaExe="$JAVA_HOME/bin/$javaCommand"                      # file name of the Java application launcher executable
javaArgs="-jar TestWriter.jar"                                  # arguments for Java launcher
javaCommandLine="$javaExe $javaArgs"                       # command line to start the Java service application
javaCommandLineKeyword="JavaWriterTest"                    # a keyword that occurs on the commandline, used to detect an already running service process and to distinguish it from others
rcFileBaseName="rc$serviceNameLo"                          # basename of the "rc" symlink file for this script
rcFileName="/usr/local/sbin/$rcFileBaseName"               # full path of the "rc" symlink file for this script
etcInitDFile="/etc/init.d/$serviceNameLo"                  # symlink to this script from /etc/init.d


Ок, жарка запускается, и даже автоматом при старте системы. Однако, не стопится, не рестартится и статус не проверяется. Как я подозреваю, сразу же после старта PID прописанный в файло меняется. Потому, команда stop не видит запущенного приложения, и выдаёт, соответственно "is not running". Статус uncheked - т.е. нет такого проуесса. Это всё до инсталла. 
После инсталла вообще странная ситуация получилась. При старте ручном говорит, что сервис уже запущен, при стопе, что сервиса нет. Бред, в общем.
Помогите с этим разобраться. В качестве доп. инфо: жарка юзается сейчас тестовая, которая тупо в ткстшку пишет. второй вариант - в консоль пишет. Жарка запускается нормально с командной строки. Выполняется правильно. При старте сервиса жарка также запускается нормально - в файл пишет. 


Это была первая часть. 

Второй вопрос. Как прописать здесь что-то а-ля 
Код

while (true){
 if (status() == false)
    restart()
 sleep(1000)
}
в старте. Чтобы после запуска скрипт сам проверял - не отвалился ли процесс.

За сим вроде бы всё. 

Это сообщение отредактировал(а) neiron - 2.9.2008, 08:49
PM MAIL   Вверх
bsa
Дата 2.9.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



Код
while true; do
    if ! getServicePID; then
        stopService && startService
    fi
done
Только это вызовет повисание, так как цикл бесконечный.
PM   Вверх
neiron
Дата 2.9.2008, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



эммм, а заслипить скрипт можно как либо? а-ля Thread.sleep(millisecond)

Видимо, придётся обёртку на сях писать. ((

а что относительно главноего вопроса? 

расставил echo
смотрю запущенные процессы. 
Всё совпадает. Т.е. у меня процесс с PID 20351 сейчас работает. echo $pid тоже 20351 показывает. В файле с пидом то же самое число. 

При этом, как я понял, проблема здесь:
Код

# Returns 0 if the process with PID $1 is our Java service process.
function checkProcessIsOurService {
   local pid="$1"
echo $pid
   if [ "$(ps -p $pid --no-headers -o comm)" != "$javaCommand" ]; then return 1; fi
   grep -q --binary -F "$javaCommandLineKeyword" /proc/$pid/cmdline
   if [ $? -ne 0 ]; then return 1; fi
echo "return 0 - PIOS"
   return 0; }


ноль не возвращается.
Функция 
Код

# Returns 0 if the process with PID $1 is running.
function checkProcessIsRunning {
   local pid="$1"
echo $pid
   if [ -z "$pid" -o "$pid" == " " ]; then return 1; fi
   if [ ! -e /proc/$pid ]; then return 1; fi
echo "return0 - PIR"
   return 0; }


отрабатывает нормально.
PM MAIL   Вверх
neiron
Дата 3.9.2008, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 18.4.2006
Где: Краснодар

Репутация: нет
Всего: 4



В общем, решилась проблема. 
Заключалась она в строчке 

javaCommandLineKeyword="JavaWriterTest"                    # a keyword that occurs on the commandline, used to detect an already running service process and to distinguish it from others

В этой строчке необходимо прописывать название приложения. 
Т.е. для jar она будет выглядеть так:
javaCommandLineKeyword="TestWriter.jar"

В остальном скрипт работает отлично. Если кто будет искать что-то подобное - советую.

обновил функцию start так:
Код

function startService {
   getServicePID
   if [ $? -eq 0 ]; then echo -n "$serviceName is already running"; rc_failed 0; rc_status -v; return 0; fi
   echo -n "Starting $serviceName   "
   startServiceProcess
   if [ $? -ne 0 ]; then rc_failed 1; rc_status -v; return 1; fi
   rc_failed 0
   rc_status -v
    while true; do
        if ! getServicePID; then
         stopService && startService
        sleep 1
        fi
    done

   return 0; }

Заинсталлил. Всё работает. Легко просмотреть статус сервиса после загрузки. В случае падения проги стартует заново. Консоль отпускает.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Linux/UNIX: Oбщие вопросы"
nickless
Imple
nerezus

В тему здесь вопросы общие - не привязанные к определенному ПО или дистрибутиву BSD/Linux/UNIX.
Например вопросы о выборе ОС для определенных задач (но если Вы просто хотите узнать "Какой дистрибутив лучше", то для этого есть Клуб юнуксоидов).
Общие вопросы по shell-программированию тоже лучше задавать здесь.


  • Вопросы мобильной разработки тут
  • Вы должны соблюдать правила форума.
  • Помните: какой вопрос, такой и ответ. Прежде чем задать вопрос прочитайте вот эту статью на форуме CIT.
  • Оскорблять запрещается.
  • Религиозные войны в Религиозных войнах.
  • Общение "просто так" в Клубе юнуксоидов. В отличие от многих других разделов, здесь разрешается сдержанно оффтопить и юморить в тему.

За интересные статьи, находки, решения, программы и просто реальную помощь будут ставиться + в репу).


В данный момент этот раздел модерируют nerezus, nickless, powerfox, pythonwin, Imple и ZeeLax. Если вы хотите помочь нам, пишите в ПМ и мы обсудим.


Спасибо. И use UNIX or die; С уважением, nerezus, nickless, powerfox, pythonwin, Imple, ZeeLax.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | *NIX системы: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0485 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.