有两种方法可以让Linux下的自己写的应用程序开机自启动。
作为测试我们可以自己先写一个测试程序:
#include
int main()
{
printf("Test start!\n");
return 0;
}
然后进行编译生成Test,其路径为/home/Test。在root权限下,在rc.local文件中写入执行命令,修改如下:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/home/Test>/dev/null 2>&1 &
exit 0
当系统重启,就会自启动Test并会后台运行。
/home/Test 表示执行这个可执行程序。
>/dev/null 表示将程序的标准输出重定向到/dev/null,/dev/null是一个空设备,将丢弃一切写入的数据。
2>&1 表示将标准出错重定向到标准输出,2和1,其实都是文件描述符,但是1前面有&,如果不加&,会认为1是一 个文件名。
& 表示这个程序在后台执行。
Linux系统有7种不同的运行级别,即0~6,7个运行级别,可以用命令runlevel查看当前系统的运行级别。
但是不同的Linux的系统运行级别定义不一样,这里主要是Debian和Redhat系列的不同,Ubuntu是基于的Debian,CentOS是基于Redhat。
debian的runlevel级别定义如下:
0:Halt,关机模式
1:Single,单用户模式
2:Full multi-user with display manager (GUI)
3:Full multi-user with display manager (GUI)
4:Full multi-user with display manager (GUI)
5:Full multi-user with display manager (GUI)
6:Reboot,重启
Ubuntu的默认开机的runlevel是2,但是可以发现runlevel 2~5都是一样的,即多用户图形模式运行,这一点和Redhat系列是有区别的。
redhat的runlevel级别定义如下:
0:系统停机状态,系统默认运行级别不能设置为0,否则不能正常启动,机器关闭。
1:单用户工作状态,root权限,用于系统维护,禁止远程登陆,就像Windows下的安全模式登录。
2:多用户状态,没有NFS支持。
3:完整的多用户模式,有NFS,登陆后进入控制台命令行模式。
4:系统未使用,保留一般不用,在一些特殊情况下可以用它来做一些事情。例如在笔记本电脑的电池用尽时,可以 切换到这个模式来做一些设置。
5:X11控制台,登陆后进入图形GUI模式,XWindow系统。
6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动。运行init6机器就会重启。
Redhat系列的runlevel 2~5划分的更为详细,我想强调的是Redhat系列的启动级别一般都是 runlevel 3 或者runlevel 5,分别表示命令行模式启动运行和图形界面模式启动运行。
第一步:编写服务脚本
脚本的文件名要与程序名保持一致。
#!/bin/bash
ProgramPath=/home/Test
ARG=$1
FunStart(){ #启动程序的函数
if [ -e $ProgramPath ];then #判断可执行文件是否存在
pid=$(pidof ${ProgramPath}) #判断这个程序是否已经启动
expr $pid + 0 >/dev/null
if [ $? -eq 0 ] && [ $pid -gt 0 ];then
echo "StartMain process already exists."
exit 0
fi
nohup $ProgramPath > /dev/null 2>&1 & #启动程序
else
echo $CollectorManger is not exists.
fi
}
FunStop(){ #停止程序的函数
pid=$(pidof ${ProgramPath}) #获取这个程序的PID
expr $pid + 0 >/dev/null #判断获得的PID是否是整数,是否大于0
if [ $? -eq 0 ] && [ $pid -gt 0 ];then
kill -9 $pid >/dev/null #杀死该程序
fi
}
#根据传进脚本的参数分别执行对应的分支
case $ARG in
start): #启动
FunStart
;;
stop): #停止
FunStop
;;
restart): #重启
FunStop
FunStart
esac
第二步:注册服务
root权限下,将脚本复制到/etc/init.d下。
service StartMain start
servive StartMain stop
service StartMain restart
可以分别完成Test程序的启动、停止、重启。注意,权限不够,要加sudo。
第三步:服务加入启动项
创建几个软链接,分别执行:
sudo ln -s /etc/init.d/Test /etc/rc0.d/K100Test
sudo ln -s /etc/init.d/Test /etc/rc2.d/S100Test
sudo ln -s /etc/init.d/Test /etc/rc3.d/S100Test
sudo ln -s /etc/init.d/Test /etc/rc5.d/S100Test
这样就完成了启动项的添加,程序开机会启动程序,关机会停止程序。对于Ubuntu只需要做前面2个链接即可,后面2个链接是为了兼容Redhat系列。系统运行在0,2,3,5级别就回去执行对应目录下的脚本即/etc/rc0.d,/etc/rc2.d/,/ect/rc3.d,/etc/rc5.d目录下脚本。
软链接的命名都是 K或者S+数字+服务脚本名,K表示kill,即stop,表示执行/etc/init.d/Test时,传入参数stop,S表示start,表示传入参数start,中间的数字表示执行顺序,因为在rcn.d目录下,有许多这样的链接,因此中间的数字决定了脚本的执行顺序,数字越小越先执行,因为有些程序之间存在依赖关系,所以顺序很重要。