非root用户执行开机启动服务脚 本
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非root用户执行开机启动服务脚 本相关的知识,希望对你有一定的参考价值。
一、需求
centos6下面添加开机服务,例如开机启动supervisor服务,然后supervisor会负责拉起配置的进程,从而实现各种服务的开机重启。
二、原理需求
在centos6下面主要通过在/etc/init.d/下面添加服务脚本和chkconfig命令来完成添加启动服务
添加服务的启停脚本
如果需要开机启动服务,或者通过service命令控制服务,必须在/etc/init.d/下面有对应服务的启停脚本,如果我们的服务为supervisor,那么在/etc/init.d/下面对应的启停脚本就是supervisor,且具有执行权限。启停脚本个格式一般都是固定的,比如包括start、stop等函数,来用来对服务进行启动/关闭
如
#!/bin/bash # # supervisord This scripts turns supervisord on # # Author: Mike McGrath <[email protected]> (based off yumupdatesd) # Jason Koppe <[email protected]> adjusted to read sysconfig, # use supervisord tools to start/stop, conditionally wait # for child processes to shutdown, and startup later # Mikhail Mingalev <[email protected]> Merged # redhat-init-jkoppe and redhat-sysconfig-jkoppe, and # made the script "simple customizable". # Brendan Maguire <[email protected]> Added OPTIONS to # SUPERVISORCTL status call # # chkconfig: 345 83 04 # # description: supervisor is a process control utility. It has a web based # xmlrpc interface as well as a few other nifty features. # Script was originally written by Jason Koppe <[email protected]>. # # usage:rename this script to ‘supervisor‘ and put it to directory /etc/init.d/ # source function library . /etc/rc.d/init.d/functions # service strips all environment variables but TERM, PATH and LANG, # so we need export those variables explicitly. # see http://unix.stackexchange.com/questions/44370/how-to-make-unix-service-see-environment-variables export HOSTNAME export USER=hadoop2 # hadoop‘s environment variables . /home/hadoop2/.bashrc SUPERVISORD=/usr/bin/supervisord SUPERVISORCTL=/usr/bin/supervisorctl PIDFILE=/tmp/supervisord.pid LOCKFILE=/tmp/supervisord OPTIONS="-c /usr/local/supervisor/supervisord.conf" # unset this variable if you don‘t care to wait for child processes to shutdown before removing the $LOCKFILE-lock WAIT_FOR_SUBPROCESSES=yes # remove this if you manage number of open files in some other fashion ulimit -n 96000 RETVAL=0 running_pid() { # Check if a given process pid‘s cmdline matches a given name pid=$1 name=$2 [ -z "$pid" ] && return 1 [ ! -d /proc/$pid ] && return 1 (cat /proc/$pid/cmdline | tr "\000" "\n"|grep -q $name) || return 1 return 0 } running() { # Check if the process is running looking at /proc # (works for all users) # No pidfile, probably no daemon present [ ! -f "$PIDFILE" ] && return 1 # Obtain the pid and check it against the binary name pid=`cat $PIDFILE` running_pid $pid $SUPERVISORD || return 1 return 0 } is_root() { current_user=`whoami` if [ "x"$current_user == "xroot" ];then echo "current_user is:"$current_user return 0 elif [ "x"$USER == "xroot" ];then echo "USER is:"$USER return 0 else return 1 fi } start() { echo "Starting supervisord: " if running ; then echo "ALREADY STARTED" return 1 fi if is_root ;then # start supervisord with options from sysconfig (stuff like -c) su hadoop2 -c "$SUPERVISORD $OPTIONS" # show initial startup status su hadoop2 -c "$SUPERVISORCTL $OPTIONS status" # only create the subsyslock if we created the PIDFILE su hadoop2 -c "[ -e $PIDFILE ] && touch $LOCKFILE" else # start supervisord with options from sysconfig (stuff like -c) $SUPERVISORD $OPTIONS # show initial startup status $SUPERVISORCTL $OPTIONS status # only create the subsyslock if we created the PIDFILE [ -e $PIDFILE ] && touch $LOCKFILE fi } stop() { echo -n "Stopping supervisord: " if is_root ;then su hadoop2 -c "$SUPERVISORCTL $OPTIONS shutdown" else $SUPERVISORCTL $OPTIONS shutdown fi if [ -n "$WAIT_FOR_SUBPROCESSES" ]; then echo "Waiting roughly 60 seconds for $PIDFILE to be removed after child processes exit" for sleep in 2 2 2 2 4 4 4 4 8 8 8 8 last; do if [ ! -e $PIDFILE ] ; then echo "Supervisord exited as expected in under $total_sleep seconds" break else if [[ $sleep -eq "last" ]] ; then echo "Supervisord still working on shutting down. We‘ve waited roughly 60 seconds, we‘ll let it do its thing from here" return 1 else sleep $sleep total_sleep=$(( $total_sleep + $sleep )) fi fi done fi # always remove the subsys. We might have waited a while, but just remove it at this point. rm -f $LOCKFILE } restart() { stop start } case "$1" in start) start RETVAL=$? ;; stop) stop RETVAL=$? ;; restart|force-reload) restart RETVAL=$? ;; reload) $SUPERVISORCTL $OPTIONS reload RETVAL=$? ;; condrestart) [ -f $LOCKFILE ] && restart RETVAL=$? ;; status) $SUPERVISORCTL $OPTIONS status if running ; then RETVAL=0 else RETVAL=1 fi ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" exit 1 esac exit $RETVAL
一些坑
开机启动的用户身份是root,可我们需要是其他用户身份,比如hadoop启动服务
使用su user -c "cmd_here" 来执行服务启动,可以用你希望的用户身份启动服务环境变量读取不到,例如JAVA_HOME等,造成服务启动不成功
这主要是service系统在执行时,会strip掉除TERM、PATH等以外所以环境变量。解决的办法是在启停服务脚本中export需要的环境变量添加或启动service时,提示No such file or directory
可能是你在windows下面编辑文件,然后上传到linux,因为windows的许多编辑器会在末尾多加换行。详细解决方案,看这里1、运行检查
cat -v /etc/init.d/your_init_script
2.解决
sed -i -e ‘s/\r//g‘ /etc/init.d/your_init_script
以上是关于非root用户执行开机启动服务脚 本的主要内容,如果未能解决你的问题,请参考以下文章
linux下如何让一个普通用户开机执行自己的一个脚本,不用root权限
Mac下用Launchd实现使用rc.local执行开机启动命令