20

I'm using CentOS 7 what my aim is to create a cron for every five seconds but as I researched we can use cron only for a minute so what I am doing now is I have created a shell file.
hit.sh

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

but I have hit it manually through right clicking it.

What I want is to create a service for that file so that i can start and stop it automatically.

I found the script to create a 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 

But I don't know what to write in start or stop methods I tried placing the same content of hit.sh in start(){} but it gave error for } in stop method.

  • Does /usr/bin/myscript work fine when you run it on its own? What is the output of echo $? when the script has completed a run? Is it 203? – Alexander Oct 15 '15 at 9:38
  • @Alexander /usr/bin/myscript.sh works fine on executing through terminal and echo$? gave me 1 – codegasmer Oct 15 '15 at 10:02
  • The script should return error code 0 if there are no problems. Error code 1 indicates an error. – Alexander Dec 6 '16 at 13:14
29

If you'd like to reuse your code sample, it could look something like:

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

Naturally, the script you want to be executed as a service should go to e.g. /usr/local/bin/hit.sh, and the above code should go to /etc/init.d/hitservice.

For each runlevel which needs this service running, you will need to create a respective symlink. For example, a symlink named /etc/init.d/rc5.d/S99hitservice will start the service for runlevel 5. Of course, you can still start and stop it manually via service hitservice start/service hitservice stop

  • Does the file need a suffix like: hitservice.service? After this: Failed to start backupservice.service: Unit not found. On CentOS 7 so why is this suggested as answer – Spektakulatius May 4 '17 at 18:24
  • @Code.IT Note that the OP wanted a SystemV script, not a systemd script, thus no suffix is needed. You should be able to run old scripts with systemd just fine though. Have you tried systemctl enable hitservice? – Dmitry Grigoryev May 5 '17 at 7:35
  • @DmitryGrigoryev: This script doesn't prevent multiple instances nor stop all multiple instances created, the pidfile stores only the last pid's spawned process. – Luciano Mar 14 '18 at 17:36
24

I believe CentOS 7 and above uses systemd. If that is the case for your system, try the following:

  1. Place the script commands you wish to run in /usr/bin/myscript.

  2. Remember to make the script executable with chmod +x.

  3. Create the following file:

/usr/lib/systemd/system/my.service

[Unit]
Description=My Script

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

[Install]
WantedBy=multi-user.target
  1. Reload all systemd service files: systemctl daemon-reload

  2. Check that it is working by starting the service with systemctl start my.

Bonus:

For testing the systemd service, it is possible to launch a tmux environment with two window panes, where the top window monitors the output from the script (stdout and stderr) and the bottom window can be used for restarting services. This requires tmux to be installed, then simply:

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

Then restart the service with:

systemctl restart my

Exit tmux with ctrl-d and then ctrl-c.

  • thanks for replying I tried you solution but the service is not starting can you look at my question I added the details – codegasmer Oct 15 '15 at 6:34
  • I think it will work if your script doesn't fail, but returns error code 0. – Alexander Oct 8 '16 at 12:48
  • 4
    Now I like systemd! – DenisKolodin Oct 19 '16 at 13:35
  • 1
    The script can be placed anywhere, as long as the systemd service can access and execute it. – Alexander Oct 1 '17 at 17:13
  • 2
    I wouldn't recommend Type=forking. Chances are the asker would need Type=simple but in general forking is not recommended: 0pointer.de/public/systemd-man/…. People have been taking their old init scripts and wrapping them in systemd so that the startup of their service goes systemd(init-script(service)). However systemd is a replacement for init scripts, so you should be calling the service directly with systemd so that it looks like systemd(service). – Centimane Jan 5 '18 at 13:42
3

This is my script as a 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
2

Take a look at fpm. It is a tool that will create init scripts for you. Works on many platforms (systemd, upstart, ect..)

https://github.com/jordansissel/fpm

0

See Bash Service Manager project: https://github.com/reduardo7/bash-service-manager

Implementation example

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

Usage example

$ ./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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.