デーモンのように起動および停止できるように、シェルスクリプトのサービスを作成するにはどうすればよいですか?


22

私はCentOS 7を使用していますが、目的は5秒ごとにcronを作成することですが、調査したところ、cronを1分間しか使用できないため、今やっていることはシェルファイルを作成したことです。
hit.sh

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

しかし、右クリックして手動でヒットしました。

私が欲しいのは、そのファイルのサービスを作成して、自動的に開始および停止できるようにすることです。

サービスを作成するスクリプトを見つけました

#!/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 

しかし、hit.shの同じコンテンツを配置しようとしたstartメソッドまたはstopメソッドに何を書くべきかわかりませんがstart(){}}in stopメソッドにエラーが発生しました。


/usr/bin/myscript、あなたが自分自身でそれを実行すると正常に動作しますか?echo $?スクリプトが実行を完了したときの出力は何ですか?203ですか?
アレクサンダー

@Alexanderは/usr/bin/myscript.shターミナルを介して実行する際に正常に動作し、echo$?私に与えました1
-codegasmer

問題がなければ、スクリプトはエラーコード0を返します。エラーコード1はエラーを示します。
アレクサンダー

回答:


30

コードサンプルを再利用する場合は、次のようになります。

#!/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 

当然、サービスとして実行するスクリプトは、たとえば/usr/local/bin/hit.shに移動し、上記のコードはに移動する必要があり/etc/init.d/hitserviceます。

このサービスの実行を必要とする各ランレベルについて、それぞれのシンボリックリンクを作成する必要があります。たとえば、という名前のシンボリックリンク/etc/init.d/rc5.d/S99hitserviceは、ランレベル5のサービスを開始します。もちろん、service hitservice start/を使用して手動で開始および停止することもできます。service hitservice stop


ファイルには、hitservice.serviceのようなサフィックスが必要ですか?この後:backupservice.serviceの開始に失敗しました:ユニットが見つかりません。CentOS 7では、なぜこれが答えとして提案されているのですか
-Spektakulatius

@ Code.IT OPはスクリプトではなくSystemVスクリプトをsystemd必要としたため、接尾辞は必要ありません。systemdただし、古いスクリプトを正常に実行できるはずです。試しましたsystemctl enable hitserviceか?
ドミトリーグリゴリエフ

@DmitryGrigoryev:このスクリプトは、複数のインスタンスを防止したり、作成された複数のインスタンスをすべて停止したりすることはありません。pidfileは、最後のpidの生成されたプロセスのみを保存します。
ルチアーノ

27

CentOS 7以降ではsystemdを使用していると思います。システムの場合は、次を試してください。

  1. 実行するスクリプトコマンドを配置します/usr/bin/myscript

  2. でスクリプトを実行可能にすることを忘れないでくださいchmod +x

  3. 次のファイルを作成します。

/etc/systemd/system/my.service

[Unit]
Description=My Script

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

[Install]
WantedBy=multi-user.target
  1. すべてのsystemdサービスファイルをリロードします。 systemctl daemon-reload

  2. でサービスを開始して、機能していることを確認しsystemctl start myます。

ボーナス:

systemdサービスをテストするために、2つのウィンドウペインでtmux環境を起動することができます。上部ウィンドウはスクリプト(stdoutおよびstderr)からの出力を監視し、下部ウィンドウはサービスの再起動に使用できます。これtmuxをインストールする必要があります、それから単純に:

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

次に、次を使用してサービスを再起動します。

systemctl restart my

終了しtmuxctrl-d、その後ctrl-c


私はあなたのソリューションを試みたが、サービスが開始されていない返信用のおかげで、あなたは私の質問を見ることができます私は詳細を追加
codegasmer

スクリプトが失敗せず、エラーコード0を返した場合に機能すると思います
アレキサンダー

4
今、私はsystemdが好きです!
デニスコロディン

1
systemdサービスがアクセスして実行できる限り、スクリプトはどこにでも配置できます。
アレクサンダー

2
私はお勧めしませんType=forking質問者が必要とする可能性はありますType=simpleが、一般的にフォークは推奨されません:0pointer.de/public/systemd-man/…systemdサービスのスタートアップが進むように、人々は古いinitスクリプトを受け取ってそれらを包み込んでいますsystemd(init-script(service))。ただしsystemd、initスクリプトに代わるものであるsystemdため、次のようにサービスを直接呼び出す必要がありますsystemd(service)
Centimane

3

これはサービスとしての私のスクリプトです:

[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


0

Bash Service Managerプロジェクトを参照してください:https : //github.com/reduardo7/bash-service-manager

実装例

#!/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

使用例

$ ./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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.