Linux下程序开机自启动

原文链接:Linux下程序开机自启动
发布时间:2015-12-12 21:23:51

在windows下使一个应用程序开机自启动,只需要把它加入开机启动项即可,那么在Linux下如何设置呢?

下面介绍两种方法可以使Linux下的应用程序开机自启动。

第一种方法:在启动脚本/etc/rc.local添加启动命令。

下面编译生成一个小程序:StartMain

1
2
3
4
5
6
7
8
9
10
11
12
13
/*************************************************************************
> File Name: StartMain.c
> Author: KentZhang
> Mail: zhchk2010@qq.com
> Created Time: 2015年12月12日 星期六 20时57分42秒
************************************************************************/

#include<stdio.h>
int main(){
printf("StartMain start!\n");
while(1);
return 0;
}

上面实例代码,仅仅3行非常简单,注意这个程序不会退出。

编译:gcc StartMain.c -o StartMain

可执行文件StarfMain的绝对路径是 /home/kent/StartMain

然后将执行命令添加到rc.local文件中,注意修改这个文件要有root权限,修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/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/kent/StartMain>/dev/null 2>&1 &

exit 0

就这样,如此简单,下次系统重启,就会自启动这个小程序StartMain。

显然仅仅添加了一句代码:

1
/home/kent/StartMain>/dev/null 2>&1 &

系统启动后会执行它,这个程序就会启动。

/home/kent/StartMain 表示执行这个可执行程序。

/dev/null 表示将程序的标准输出重定向到/dev/null,/dev/null是一个空设备,将丢弃一切写入的数据。

2>&1 表示将标准出错重定向到标准输出,2和1,其实都是文件描述符,但是1前面有&,如果不加&,会认为1是一个文件名。

& 表示这个程序在后台执行,这个&符号,一定要有!!!!本例中的程序不会退出,不在后台执行,那么这句shell 命令会一直等待返回,但是程序不会结束,所以不会返回,那么系统将会卡死在这里,不能正常启动,这一点要切记!!!

第二种方法:将程序注册成服务。

在这里首先介绍一下Linux系统运行级别的概念,在windows系统启动时,可以以安全模式启动,显然与正常启动的不同,可以类似看做不同的运行级别。而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,分别表示命令行模式启动运行和图形界面模式启动运行。

下面正式介绍如何将一个程序注册服务并使之开机启动,本例是以Ubuntu 12.04为测试机:

第一步:编写服务脚本。

代码如下,是一个shell脚本StartMain,该脚本的文件名要与程序名保持一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#########################################################################
# File Name: StartMain
# Author: KentZhang
# mail: zhchk2010@qq.com
# Created Time: 2015年12月13日 星期日 08时32分11秒
#########################################################################
#!/bin/bash

ProgramPath=/home/kent/StartMain
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

第二步:注册服务

将上面编写的脚本复制到/etc/init.d目录下,注意需要root权限。

此时,程序StartMain程序已经注册成服务,在任意工作目录下,执行shell:

1
2
3
4
5
service StartMain start

servive StartMain stop

service StartMain restart

可以分别完成StartMain程序的启动、停止、重启。注意,权限不够,要加sudo。

第三步:将服务加入启动项

这一步,就是创建几个软链接,分别执行:

1
2
3
4
5
6
7
sudo ln -s  /etc/init.d/StartMain  /etc/rc0.d/K100StartMain

sudo ln -s /etc/init.d/StartMain /etc/rc2.d/S100StartMain

sudo ln -s /etc/init.d/StartMain /etc/rc3.d/S100StartMain

sudo ln -s /etc/init.d/StartMain /etc/rc5.d/S100StartMain

这样就完成了启动项的添加,程序开机会启动程序,关机会停止程序。

对于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/StartMain时,传入参数stop,S表示start,表示传入参数start,中间的数字表示执行顺序,因为在rcn.d目录下,有许多这样的链接,因此中间的数字决定了脚本的执行顺序,数字越小越先执行,有时候程序之间有依赖性,这个顺序也是非常重要。

以上就是设置Linux程序开机自启动的2种方法,如有错误,欢迎指正。