web-dev-qa-db-fra.com

Comment créer un service pour un script Shell afin de pouvoir le démarrer et l'arrêter comme un démon?

J'utilise CentOS 7, mon objectif est de créer un cron toutes les cinq secondes, mais pendant mes recherches, nous ne pouvons utiliser cron que pendant une minute, donc ce que je fais maintenant, c'est que j'ai créé un fichier Shell.
hit.sh

while sleep 5; do curl http://localhost/test.php; done

mais je l'ai frappé manuellement en faisant un clic droit dessus.

Ce que je veux, c'est créer un service pour ce fichier afin que je puisse le démarrer et l'arrêter automatiquement.

J'ai trouvé le script pour créer un service

#!/bin/bash
# chkconfig: 2345 20 80
# description: Description comes here....

# Source function library.
. /etc/init.d/functions

start() {
    # code to start app comes here 
    # example: daemon program_name &
}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

Mais je ne sais pas quoi écrire dans les méthodes de démarrage ou d'arrêt. J'ai essayé de placer le même contenu de hit.sh dans start(){} mais cela a donné une erreur pour } Dans la méthode d'arrêt.

23
codegasmer

Si vous souhaitez réutiliser votre exemple de code, il pourrait ressembler à:

#!/bin/bash

case "$1" in 
start)
   /path/to/hit.sh &
   echo $!>/var/run/hit.pid
   ;;
stop)
   kill `cat /var/run/hit.pid`
   rm /var/run/hit.pid
   ;;
restart)
   $0 stop
   $0 start
   ;;
status)
   if [ -e /var/run/hit.pid ]; then
      echo hit.sh is running, pid=`cat /var/run/hit.pid`
   else
      echo hit.sh is NOT running
      exit 1
   fi
   ;;
*)
   echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

Naturellement, le script que vous souhaitez exécuter en tant que service doit aller par ex. /usr/local/bin/hit.sh, et le code ci-dessus devrait aller à /etc/init.d/hitservice.

Pour chaque niveau d'exécution nécessitant l'exécution de ce service, vous devrez créer un lien symbolique respectif. Par exemple, un lien symbolique nommé /etc/init.d/rc5.d/S99hitservice démarrera le service pour le niveau d'exécution 5. Bien sûr, vous pouvez toujours le démarrer et l'arrêter manuellement via service hitservice start/service hitservice stop

31
Dmitry Grigoryev

Je crois que CentOS 7 et supérieur utilise systemd. Si tel est le cas pour votre système, essayez ce qui suit:

  1. Placez les commandes de script que vous souhaitez exécuter dans /usr/bin/myscript.

  2. N'oubliez pas de rendre le script exécutable avec chmod +x.

  3. Créez le fichier suivant:

/ etc/systemd/system/my.service

[Unit]
Description=My Script

[Service]
Type=forking
ExecStart=/usr/bin/myscript

[Install]
WantedBy=multi-user.target
  1. Rechargez tous les fichiers de service systemd: systemctl daemon-reload

  2. Vérifiez qu'il fonctionne en démarrant le service avec systemctl start my.

Bonus:

Pour tester le service systemd, il est possible de lancer un environnement tmux avec deux volets de fenêtre, où la fenêtre supérieure surveille la sortie du script (stdout et stderr) et la fenêtre inférieure peut être utilisé pour redémarrer les services. Cela nécessite l'installation de tmux, puis simplement:

tmux new-session \; select-layout even-horizontal \; split-window -v journalctl -o cat --since=@$(date +%s) -f -u my \; rotate-window \; set -g status-bg colour0 \; set -g status-fg colour9 \; attach

Redémarrez ensuite le service avec:

systemctl restart my

Quittez tmux avec ctrl-d et alors ctrl-c.

28
Alexander

Voici mon script en tant que service:

[Unit]
Description=To change In test buffer
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/test.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target
3
decimal

Jetez un oeil à fpm. C'est un outil qui créera pour vous des scripts d'initialisation. Fonctionne sur de nombreuses plateformes (systemd, upstart, ect ..)

https://github.com/jordansissel/fpm

2
spuder

Voir Projet Bash Service Manager : https://github.com/reduardo7/bash-service-manager

Exemple d'implémentation

#!/usr/bin/env bash

export PID_FILE_PATH="/tmp/my-service.pid"
export LOG_FILE_PATH="/tmp/my-service.log"
export LOG_ERROR_FILE_PATH="/tmp/my-service.error.log"

. ./services.sh

run-script() {
  local action="$1" # Action

  while true; do
    echo "@@@ Running action '${action}'"
    echo foo
    echo bar >&2

    [ "$action" = "run" ] && return 0
    sleep 5
    [ "$action" = "debug" ] && exit 25
  done
}

before-start() {
  local action="$1" # Action

  echo "* Starting with $action"
}

after-finish() {
  local action="$1" # Action
  local serviceExitCode=$2 # Service exit code

  echo "* Finish with $action. Exit code: $serviceExitCode"
}

action="$1"
serviceName="Example Service"

serviceMenu "$action" "$serviceName" run-script "$workDir" before-start after-finish

Exemple d'utilisation

$ ./example-service
# Actions: [start|stop|restart|status|run|debug|tail(-[log|error])]

$ ./example-service start
# Starting Example Service service...

$ ./example-service status
# Serive Example Service is runnig with PID 5599

$ ./example-service stop
# Stopping Example Service...

$ ./example-service status
# Service Example Service is not running
1
Eduardo Cuomo