[关闭]
@xtccc 2015-09-21T13:44:56.000000Z 字数 3150 阅读 8845

在Linux中创建自己的Service

Email me
GitHub

Linux


之前写的应用,都是通过直接敲命令/写成script的形式在前台或者后台运行。如果能用 service {app-name} start/stop/status的形式来启动app/停止app/查看运行状态,就更方便和简洁了。

实现一个custom service 需要自己写init script,这就离不开shell script的帮助,这里有一篇还不错的教程 —— Advanced Bash-Scripting Guide


Skeleton Script

CentOS系统自带一个关于怎样写init script的文档,路径是 /usr/share/doc/initscripts-*/sysvinitfiles ,这里可以直接查看内容


简单的service

下面,通过一个简单的例子,来实现利用service {service-name} start启动一个APP。

以下是Python写的APP,文件名为 /home/tao/xt-job.py

  1. # -*- encoding: utf-8 -*-
  2. import time
  3. import sys
  4. def main(args):
  5. for i in range(0, len(args)):
  6. print "args[" + str(i) + "] = ", args[i]
  7. for i in range(0, 5):
  8. print "hello ", i
  9. time.sleep(1)
  10. print "bye"
  11. if __name__ == "__main__":
  12. main(sys.argv)



现在,我们希望通过命令 service xt-service start 来运行这个app,那么,我们可以在目录 /etc/init.d 中创建一个名为 xt-service 的文件,其内容为:

  1. #!/bin/bash
  2. . /etc/init.d/functions
  3. SERVICE_NAME="xiaotao-service"
  4. RETVAL=0
  5. start() {
  6. echo -n "Starting $SERVICE_NAME: "
  7. python -m /home/tao/xt-job 100 200 300
  8. RETVAL=$?
  9. }
  10. case "$1" in
  11. start)
  12. start
  13. ;;
  14. *)
  15. echo "Now only `start` is available"
  16. ;;
  17. esac
  18. exit $RETVAL



好,现在我们试一试。
运行命令:

# service xt-service start



输出如下:

Starting xiaotao-service: args[0] = //home/tao/xt-job.py
args[1] = 100
args[2] = 200
args[3] = 300
hello 0
hello 1
hello 2
hello 3
hello 4
bye

预想的功能实现了!


更加全面的service

在现实中,一个service需要实现的功能包含以下几个:
1. 令APP在后台运行,shell不输出;
2. 除了可以启动APP(start),还可以停止APP(stop),重启APP(restart),并可以查看其状态(status);

首先,我们把上面Python写成的APP改一改,让它每隔1秒往指定文件中输出一个数字,共输出50个数字,耗时50秒左右。

  1. # -*- encoding: utf-8 -*-
  2. # /home/tao/xt-daemon-job.py
  3. import sys
  4. import time
  5. def main(args):
  6. for i in range(0, len(args)):
  7. print "args[" + str(i) + "] = ", args[i]
  8. # 每隔1秒向文件中写入一个数字,共写入50个数字
  9. with open(args[1], "w") as f:
  10. for i in range(0, 500):
  11. time.sleep(1)
  12. f.write(str(i) + "\n")
  13. if __name__ == "__main__":
  14. main(sys.argv)



下面,创建名为 /etc/init.d/xt-daemon-service 的文件。

  1. #!/bin/bash
  2. . /etc/init.d/functions
  3. SERVICE_NAME="xiaotao-daemon-service"
  4. RETVAL=0
  5. PID=-1
  6. PIDFILE=/var/run/${SERVICE_NAME}.PID
  7. start() {
  8. # 首先检查PID文件是否已存在
  9. if [ -f ${PIDFILE} ]; then
  10. echo "PID file ${PIDFILE} already exists, please stop the service !"
  11. exit
  12. fi
  13. echo "Starting service ${SERVICE_NAME} ..."
  14. # >/dev/null 2>&1 表示不输出stdout和stderr
  15. # 最后一个 & 表示整个命令在后台执行
  16. cd "/home/tao/"
  17. python -m xt-daemon-job A >/dev/null 2>&1 &
  18. PID=$! # 获取本shell启动的最后一个后台程序的进程号(PID)
  19. if [ -z ${PID} ]; then # 检查有没有获取到pid
  20. echo "Failed to get the process id, exit!"
  21. exit
  22. else
  23. echo "Starting successfully, whose pid is ${PID}"
  24. fi
  25. touch $PIDFILE
  26. echo ${PID} > ${PIDFILE}
  27. }
  28. stop() {
  29. if [ -f $PIDFILE ]; then # 检查PIDFILE是否存在
  30. PID=`cat ${PIDFILE}`
  31. if [ -z $PID ]; then # 检查PID是否存在于PIDFILE中
  32. echo "PIDFILE $PIDFILE is empty !"
  33. exit
  34. fi
  35. # 检查该进程是否存在
  36. if [ -z "`ps axf | grep $PID | grep -v grep`" ]; then
  37. echo "Process dead but pidfile exists!"
  38. exit
  39. else
  40. kill -9 $PID
  41. echo "Stopping service successfully , whose pid is $PID"
  42. rm -f $PIDFILE
  43. fi
  44. else
  45. echo "File $PIDFILE does NOT exist!"
  46. fi
  47. }
  48. restart() {
  49. stop
  50. start
  51. }
  52. status() {
  53. # 检查pid file是否存在
  54. if [ -f $PIDFILE ]; then
  55. PID=`cat $PIDFILE`
  56. # 检查pid file是否存在pid
  57. if [ -z $PID ] ; then
  58. echo "No effective pid but pidfile exists!"
  59. else
  60. # 检查pid对应的进程是否还存在
  61. if [ -z "`ps axf | grep $PID | grep -v grep`" ]; then
  62. echo "Process dead but pidfile exist"
  63. else
  64. echo "Running"
  65. fi
  66. fi
  67. else
  68. echo "Service not running"
  69. fi
  70. }
  71. case "$1" in
  72. start)
  73. start
  74. ;;
  75. stop)
  76. stop
  77. ;;
  78. restart)
  79. restart
  80. ;;
  81. status)
  82. status
  83. ;;
  84. *)
  85. echo "Usage: xt-daemon-service {start|stop|restart|status}"
  86. ;;
  87. esac



以上代码相当地self explainatory,下面还是简单地对要点做个总结:

  1. start app时,首先检查app是否正在运行。如果没有运行,则启动app,并创建一个pidfile,将app的pid写入pidfile中;

  2. stop app时,首先检查app是否正在运行。如果正在运行,则kill app并删除pidfile;

  3. 查看app status时,查找pidfile中的pid,并用 ps axf 命令来查看该pid对应的进程是否正在运行;
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注