<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>绿色记忆 &#187; SystemV</title>
	<atom:link href="https://blog.gmem.cc/tag/systemv/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.gmem.cc</link>
	<description></description>
	<lastBuildDate>Tue, 21 Apr 2026 10:40:56 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.14</generator>
	<item>
		<title>Linux运行级别和启动顺序</title>
		<link>https://blog.gmem.cc/linux-run-level</link>
		<comments>https://blog.gmem.cc/linux-run-level#comments</comments>
		<pubDate>Thu, 05 Apr 2012 06:33:21 +0000</pubDate>
		<dc:creator><![CDATA[Alex]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Linux知识]]></category>
		<category><![CDATA[SystemV]]></category>

		<guid isPermaLink="false">http://blog.gmem.cc/?p=1251</guid>
		<description><![CDATA[<p>本文主要介绍Sysvinit初始化系统，牵涉到一部分upstart的知识。参考Linux的三种Init机制详细的了解Linux系统的初始化机制。 运行级别 标准的Linux运行级别定义 一共有7个运行级别： 运行级别 说明 0  停机，机器关闭 1  单用户模式 2  没有用到/可以用户自定义 3  完全多用户模式，没有图形界面 4  没有用到/可以用户自定义 5  完全多用户模式，有图形界面 6  重新启动 Debian及其衍生的系统（例如Ubuntu）运行级别定义 一共有7个运行级别，但是2-5没有区别 <a class="read-more" href="https://blog.gmem.cc/linux-run-level">[...]</a></p>
<p>The post <a rel="nofollow" href="https://blog.gmem.cc/linux-run-level">Linux运行级别和启动顺序</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></description>
				<content:encoded><![CDATA[<div class="wri_content_clear_both"><p>本文主要介绍Sysvinit初始化系统，牵涉到一部分upstart的知识。参考<a href="https://blog.gmem.cc/linux-init-mechanisms">Linux的三种Init机制</a>详细的了解Linux系统的初始化机制。</p>
<div class="blog_h2"><span class="graybg">运行级别</span></div>
<div class="blog_h3"><span class="graybg">标准的Linux运行级别定义</span></div>
<div>一共有7个运行级别：</div>
<div>
<table style="width: 100%;" border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="width: 100px; text-align: center;">运行级别</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td> 停机，机器关闭</td>
</tr>
<tr>
<td>1</td>
<td> 单用户模式</td>
</tr>
<tr>
<td>2</td>
<td> 没有用到/可以用户自定义</td>
</tr>
<tr>
<td>3</td>
<td> 完全多用户模式，没有图形界面</td>
</tr>
<tr>
<td>4</td>
<td> 没有用到/可以用户自定义</td>
</tr>
<tr>
<td>5</td>
<td> 完全多用户模式，有图形界面</td>
</tr>
<tr>
<td>6</td>
<td> 重新启动</td>
</tr>
</tbody>
</table>
</div>
<div class="blog_h3"><span class="graybg">Debian及其衍生的系统（例如Ubuntu）运行级别定义</span></div>
<div>一共有7个运行级别，但是2-5没有区别</div>
<div>
<table style="width: 100%;" border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="width: 100px; text-align: center;">运行级别</td>
<td style="text-align: center;">说明</td>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td> 停机，机器关闭</td>
</tr>
<tr>
<td>1</td>
<td> 单用户模式</td>
</tr>
<tr>
<td>2</td>
<td> 完全多用户模式，有图形界面</td>
</tr>
<tr>
<td>3</td>
<td> 完全多用户模式，有图形界面</td>
</tr>
<tr>
<td>4</td>
<td> 完全多用户模式，有图形界面</td>
</tr>
<tr>
<td>5</td>
<td> 完全多用户模式，有图形界面</td>
</tr>
<tr>
<td>6</td>
<td> 重新启动</td>
</tr>
</tbody>
</table>
</div>
<div class="blog_h3"><span class="graybg">检查和修改系统的默认运行级别</span></div>
<pre class="crayon-plain-tag">#查看运行级别命令
runlevel

#修改运行级别
sudo vi /etc/inittab
#添加以下内容，则默认运行级别修改3
id:3:initdefault:
#重启后，再使用命令runlevel查看，会发现运行级别变成了3

#下面是个非主流重启操作
sudo init 6</pre>
<div class="blog_h3"><span class="graybg">不同运行级别到底有什么区别</span></div>
<p>不同运行级别，会执行不同的脚本，这些脚本是在：/etc/rc0.d 到 /etc/rc5.d这些目录中定义的，目录名中的数字和运行级别对应。<br /> 这些脚本都是指向/etc/init.d/下文件的符号连接。如果你留意的话，发现这些脚本均是以如下方式命名：</p>
<table border="1" cellspacing="0" cellpadding="5">
<thead>
<tr>
<td style="text-align: center;">前缀</td>
<td style="text-align: center;">两位数字</td>
<td style="text-align: center;">脚本名称</td>
</tr>
</thead>
<tbody>
<tr>
<td>可以是K或者S</td>
<td>表示脚本被执行的顺序</td>
<td>/etc/init.d中对应脚本的名称</td>
</tr>
</tbody>
</table>
<p>例如：S91apache2、K09apache2等。</p>
<p>前缀<span style="color: #000000;"><strong><span style="background-color: #99cc00;">S</span></strong></span>或者<span style="color: #000000;"><strong><span style="background-color: #ff0000;">K</span></strong></span>表示<strong><span style="background-color: #99cc00; color: #000000;">启动</span></strong>或者<strong><span style="background-color: #ff0000; color: #000000;">停止</span></strong>某个服务。分别会调用init.d下脚本的do_start()、do_stop()函数。</p>
<p>如果要在运行级别N下禁用服务myservice，则只需要删除rcN.d中删除符号连接，例如：</p>
<pre class="crayon-plain-tag">#进入运行级别2的目录
cd /etc/rc2.d
#修改前缀S为K
rm S11myservice</pre>
<div class="blog_h2"><span class="graybg">自定义服务</span></div>
<p>Linux下的<pre class="crayon-plain-tag">service</pre> 命令可以用于启动或者停止一个服务，该命令会<span style="background-color: #c0c0c0;">忽略大部分环境变量</span>，并且设置工作目录为<pre class="crayon-plain-tag">/</pre> 。</p>
<p>该命令的本质执行以下二者之一：</p>
<ol>
<li>执行位于/etc/init.d/下的System V init script</li>
<li>执行位于/etc/init/下的启动任务（upstart job）</li>
</ol>
<div class="blog_h3"><span class="graybg">System V init脚本模板</span></div>
<p>因此，我们只需要编写符合规范的脚本，并按照上一节描述的命名规则放置到对应位置，即可自己定义“服务”，下面是Ubuntu 14的System V init脚本的模板：</p>
<pre class="crayon-plain-tag">#! /bin/sh
### BEGIN INIT INFO
# Provides:          Sample daemon
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: System V init script  example
# Description:       System V init script  example
### END INIT INFO

#注意，上面的INIT INFO会被chkconfig命令读取，自动完成/etc/rc*.d中符号链接的更新
# Author: Alex Wang


# 如当前服务在mountnfs.sh后运行，PATH只应当包含/usr/*下的内容
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="System V init script  example"
NAME=smpld
# 守护程序的路径
DAEMON=/usr/local/bin/$NAME
DAEMON_ARGS="--msg HelloWorld"
#写入进程ID的文件
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# 如果守护程序不可执行，则退出
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] &amp;&amp; . /etc/default/$NAME

# 加载rcS变量
. /lib/init/vars.sh

# 执行此文件以定义LSB log_*函数
. /lib/lsb/init-functions

#
# 用于启动（S）守护程序/服务的函数
#
do_start()
{
	# 返回值说明：
	#   0 守护程序启动成功
	#   1 守护程序（在此函数执行之前）已经启动
	#   2 守护程序无法启动
    # 一般使用start-stop-daemon来进行守护程序的启动与关闭
    # 测试守护程序是否已经被启动
	#   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test &gt; /dev/null || return 1
    # 尝试启动守护程序
	#   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_ARGS || return 2
	# 添加额外的代码，例如等待进程准备好提供服务，或者仅仅是等待一段时间。等待以便依赖于此守护程序的其它Daemon能够启动
    $DAEMON $DAEMON_ARGS
}

#
# 用于停止（K）守护程序/服务的函数
#
do_stop()
{
	# 返回值说明：
	#   0 守护程序停止成功
	#   1 守护程序（在此函数执行之前）已经停止
	#   2 守护程序无法停止
	#   其它值：有错误发生
    # 一般使用start-stop-daemon来进行守护程序的启动与关闭
	#   start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
	#   RETVAL="$?"
	#   [ "$RETVAL" = 2 ] &amp;&amp; return 2
    #
	# 等待守护程序fork出的子进程停止：
	#   start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
    #	[ "$?" = 2 ] &amp;&amp; return 2
	# 某些守护程序不会删除其PID文件，需要手工删除
	#  rm -f $PIDFILE
	#  return "$RETVAL"
}

#
# 用户发送SIGHUP信号给守护程序的函数
#
do_reload() {
	# start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
	return 0
}

#根据第一个参数是start、stop、reload……，执行不同的函数
case "$1" in
  start)
	[ "$VERBOSE" != no ] &amp;&amp; log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] &amp;&amp; log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 1 ;;
	esac
	;;
  status)
	status_of_proc "$DAEMON" "$NAME" &amp;&amp; exit 0 || exit $?
	;;
  reload|force-reload)

	log_daemon_msg "Reloading $DESC" "$NAME"
	do_reload
	log_end_msg $?
	;;
  restart|force-reload)
	log_daemon_msg "Restarting $DESC" "$NAME"
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # 旧的进程仍然在运行
			*) log_end_msg 1 ;; # 启动失败
		esac
		;;
	  *)
		# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" &gt;&amp;2
	exit 3
	;;
esac
#空命令，返回0
:</pre>
<div class="blog_h3"><span class="graybg">System V init脚本样例</span></div>
<p>下面是实际中的一个具体例子：</p>
<pre class="crayon-plain-tag">#! /bin/sh
### BEGIN INIT INFO
# Provides:          tomcat7d
# Required-Start:    $syslog
# Required-Stop:     $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Gmem tomcat7d daemon
# Description:       Gmem tomcat7d daemon
### END INIT INFO

# Author: Alex Wang

export PDT_DIR=/usr/local/Tomcat7
. $PDT_DIR/setenv.sh
LOG_FILE=$LOG_DIR/tomcat7d.log
touch $LOG_FILE
 
do_log()
{
    echo `date "+%Y-%m-%d %H:%M:%S"` $1 &gt;&gt; $LOG_FILE
    echo $1
}

do_start()
{    
    ps -fC "mysqld_safe" | grep "$PDT_DIR/db/my.cnf" &gt; /dev/null
    if [[ $? -eq 0 ]]; then
        do_log "$PDT_NAME database service is already up."
    else
        do_log "Starting $PDT_NAME database service..."
        $PDT_DIR/startup-db.sh
    fi
       
    ps -fC "java"  | grep "$PDT_DIR/jre/bin/java" &gt; /dev/null
    if [[ $? -eq 0 ]]; then
        do_log "$PDT_NAME application service is already up."
    else
        do_log "Starting $PDT_NAME application service..."
        $PDT_DIR/startup-app.sh
    fi
    
    return 0
}

do_stop()
{
    ps -fC "mysqld_safe" | grep "$PDT_DIR/db/my.cnf" &gt; /dev/null
    if [[ $? -eq 0 ]]; then
        do_log "Stopping $PDT_NAME database service..."
        $PDT_DIR/db/bin/mysqladmin -uroot -hlocalhost --protocol=tcp shutdown
        do_log "$PDT_NAME database service stopped."
    else
        do_log "$PDT_NAME database service is already down."
    fi
       
    ps -fC "java"  | grep "$PDT_DIR/jre/bin/java" &gt; /dev/null
    if [[ $? -eq 0 ]]; then
        do_log "Stopping $PDT_NAME application service..."
        $PDT_DIR/bin/shutdown.sh
        do_log "$PDT_NAME application service stopped."
    else
        do_log "$PDT_NAME application service is already down."
    fi
    
    return 0
}

case "$1" in
  start)
  do_start
  ;;
  stop)
  do_stop
  ;;
  restart)
  do_stop
  do_start
  ;;
esac

:
#该脚本放置于/etc/init.d下
#执行命令： chkconfig --add tomcat7d 即可注册服务</pre>
<div class="blog_h3"><span class="graybg">注册服务</span></div>
<p>命令<pre class="crayon-plain-tag">chkconfig</pre> 用于配置系统启动时服务的行为，新近的Ubuntu版本已经不支持该命令，使用<pre class="crayon-plain-tag">update-rc.d</pre> 命令代替之：</p>
<pre class="crayon-plain-tag">sudo update-rc.d myservice defaults</pre>
<div class="blog_h2"><span class="graybg">启动脚本rc.local</span></div>
<p>在Ubuntu下，你可能会注意到rc2.d - rc5.d里面有一个数字最大的<span style="color: #000000;"><span style="background-color: #ff0000;">S99</span><span style="background-color: #ff0000;"><strong>rc.local</strong></span></span>文件，查看其链接目标/etc/init.d/rc.local ，可以看到类似如下脚本：</p>
<pre class="crayon-plain-tag">#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.local
# Required-Start:    $all
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Run /etc/rc.local if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_start() {
	if [ -x /etc/rc.local ]; then
	        [ "$VERBOSE" != no ] &amp;&amp; log_begin_msg "Running local boot scripts (/etc/rc.local)"
		/etc/rc.local
		ES=$?
		[ "$VERBOSE" != no ] &amp;&amp; log_end_msg $ES
		return $ES
	fi
}

case "$1" in
    start)
	do_start
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" &gt;&amp;2
        exit 3
        ;;
    stop)
        ;;
    *)
        echo "Usage: $0 start|stop" &gt;&amp;2
        exit 3
        ;;
esac</pre>
<p>在执行S操作的时候，/etc/init.d/rc.local 会调用脚本<span style="color: #000000;"><strong><span style="background-color: #99cc00;">/etc/rc.local</span></strong></span>，我们常常用<span style="color: #000000; background-color: #99cc00;"><strong>这个脚本</strong></span>来执行一些操作：这些操作在<span style="color: #000000;"><strong><span style="background-color: #99cc00;">所有系统服务启动完毕后</span></strong></span>执行。</p>
<div class="blog_h2"><span class="graybg">Linux系统启动时执行脚本的整体步骤</span></div>
<p>脚本执行由<pre class="crayon-plain-tag">init</pre> 进程发起，以Ubuntu为例，步骤如下：</p>
<div>
<ol>
<li><pre class="crayon-plain-tag">/etc/init/</pre> 目录下的所有*.conf文件被执行，这些文件可能具有类似如下的内容：<br />
<pre class="crayon-plain-tag">description     "deferred execution scheduler"
#启动的时机，可能是运行级别（runlevel）、文件系统（filesystem）等
start on runlevel [2345]
stop on runlevel [!2345]

expect fork
respawn

exec atd</pre>
</li>
<li><pre class="crayon-plain-tag">/etc/rc*.d/</pre> 目录下的脚本，按照顺序执行</li>
<li><pre class="crayon-plain-tag">/etc/rc.local</pre> 脚本被执行</li>
</ol>
</div>
</div><p>The post <a rel="nofollow" href="https://blog.gmem.cc/linux-run-level">Linux运行级别和启动顺序</a> appeared first on <a rel="nofollow" href="https://blog.gmem.cc">绿色记忆</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.gmem.cc/linux-run-level/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
