linux 系统启动以后,执行脚本的顺序

本文详细解析了嵌入式系统启动过程中的关键脚本,包括rcS、rc.user及env.sh,阐述了虚拟文件系统挂载、网络参数配置、服务启动等核心操作,为理解嵌入式Linux启动流程提供了深入视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 首先是 rcS

#! /bin/sh

export PATH=/bin:/sbin:/usr/bin:/usr/sbin:.

# 挂载虚拟文件系统
echo "Mounting virtual filesystems"
mkdir -p /sys /proc /dev
mount -t proc proc /proc
mount -t sysfs sys /sys
if grep -qs debugfs /proc/filesystems; then
	mount -t debugfs debugfs /sys/kernel/debug
fi
if grep -qs configfs /proc/filesystems; then
	mount -t configfs none /sys/kernel/config
fi
grep -q devtmpfs /proc/mounts || mount -t devtmpfs none /dev
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mount -t tmpfs -o mode=01777 tmpfs /tmp
mkdir -p /dev/shm
mount -t tmpfs -o noexec,nosuid,nodev,mode=1777 shm /dev/shm

# 执行系统参数配置(网络参数设置,就是写到了这个文件里面)
if [ -e /etc/sysctl.conf ]; then
	for conf in /etc/sysctl.conf /etc/sysctl.d/*.conf; do
		if [ -r "$conf" ]; then
			sysctl -p "$conf" > /dev/null
		fi
	done
fi

echo "/sbin/stbhotplug" > /proc/sys/kernel/hotplug

if [ ! -z "$BASH_VERSION" ]; then
	# Recovery from missing /dev/console (works on bash but not ash)
	exec < /dev/console >& /dev/console
fi

# Don't let SCHED_FIFO / SCHED_RR realtime threads get preempted
echo -1 > /proc/sys/kernel/sched_rt_runtime_us

# By default, switch to conservative governor on SoCs with AVS CPUfreq only
cpufreq-info -d | grep 'brcm.*avs' >/dev/null
if [ $? = 0 ]; then
	# Check if system supports the conservative governor and enable it
	cpufreq-info -g | grep conservative >/dev/null
	if [ $? = 0 ]; then
		echo "Switching to conservative governor"
		cpufreq-set -g conservative
	fi
fi

# GPLv3 warning
if [ -e /bin/gdbserver -o -e /bin/gdb ]; then
	echo "* WARNING: THIS STB CONTAINS GPLv3 SOFTWARE"
	echo "* GPLv3 programs must be removed in order to enable security."
	echo "* See: http://www.gnu.org/licenses/gpl-faq.html#Tivoization"
fi

# -small configuration: do not start any other services automatically
if [ ! -e /bin/login ]; then
	[ -f /root/rc.user ] && sh /root/rc.user
	exit 0
fi

# Set up MoCA link, if present
[ -e /dev/bmoca0 ] && mocacfg boot &

cmdline=`cat /proc/cmdline`

if [[ "$cmdline" != *nfsroot=* ]]; then
	# Make sure ethX appear(s) first, which is relevant for DSA enabled
	# systems where ethX (conduit interface) needs to be brought up first
	# before all other DSA created network interfaces
	ifaces="$(ls /sys/class/net | grep eth) $(ls /sys/class/net | grep -v eth)"
	for x in $ifaces; do
	if [[ "$x" =~ ^eth* ]] || [[ $x =~ ^ra* ]] || [[ "$x" =~ ^wlan* ]] || [[ "$x" =~ ^lo* ]];then
		echo "Configuring $x interface"
		/sbin/ifup $x
        fi
	done
else
	# just configure loopback
	/sbin/ifup lo
fi

# Set up WLAN, if present
if [ -e /etc/wl/rtecdc.trx -a -x /bin/bcmdl ]; then
	bcmdl /etc/wl/rtecdc.trx
fi
[ -e /lib/modules/wl.ko ] && insmod /lib/modules/wl.ko

# rootfs on SATA hard disk (but not sda4-less thumbdrive)
if [ -e /dev/root -a "`readlink /dev/root`" = "sda1" -a -e /dev/sda4 ]; then
	mount -o remount,noatime,commit=1 /
	mount -a
	swapon -a
fi

echo "Starting network services"
portmap &

# 执行rc.user脚本
if [ -f /root/rc.user ]; then
	echo "Starting user services"
	/bin/sh /root/rc.user
fi

2 第二个脚本 /root/rc.user 

#! /bin/sh

# 创建这些目录
grep -q "tmpfs /var" /proc/mounts || mount -t tmpfs -o size=4M,mode=01777 tmpfs /var
mkdir -p /var/log
mkdir -p /var/run
mkdir -p /var/tmp
grep -q "tmpfs /mnt" /proc/mounts || mount -t tmpfs -o size=64k,mode=01777 tmpfs /mnt
mkdir -p /mnt/tnfs
mkdir -p /mnt/nfs

# 新建链接
# create the symlinks of flash partition layout
FLASH_PARTS_NAME=(partsinfo partsinfobak manufactory bootparam bootparambak nvram security securitybak splash fsikernel fsirootfs ssikernel ssirootfs hwcfg tnfs rwfs bsu boot system bootloader userdata)
FLASH_PARTS_NUM=${#FLASH_PARTS_NAME[*]}

mkdir -p /dev/block/by-name
for((i=0;i<${FLASH_PARTS_NUM};i=${i}+1))
do
    if [ -b "/dev/mmcblk0p$((i+1))" -a ! -e "/dev/block/by-name/${FLASH_PARTS_NAME[${i}]}" ]; then
        ln -s /dev/mmcblk0p$((i+1)) /dev/block/by-name/${FLASH_PARTS_NAME[${i}]}
    fi
done

# 执行env.sh
if [ -f "/etc/init.d/env.sh" ]; then
    source /etc/init.d/env.sh
fi

# 执行"S开头"的脚本
# 命令set的用法
# set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]
# 此处的 set start,是指 set [arg ...]
# The remaining n ARGs are positional parameters and are assigned, in order, to $1, $2, 
# .. $n.  If no ARGs are given, all shell variables are printed.(from man page)
#
#
# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do

     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue

     case "$i" in
	*.sh)
	    # Source shell script for speed.
	    (
		trap - INT QUIT TSTP
		set start
		. $i
	    )
	    ;;
	*)
	    # No sh extension, so fork subprocess.
	    $i start
	    ;;
    esac
done

 

3 env.sh 设置环境变量

# 设置环境变量
export PATH=$PATH:.:/sbin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/bin/wireless:/usr/local/bin/tcpdump:/usr/local/bin/curl:/usr/local/bin/dbus:/nano-lamp/usr/bin:/nano-lamp/usr/sbin:/usr/local/bin/netflix
export LD_LIBRARY_PATH=.:/usr/local/lib:$LD_LIBRARY_PATH

export SSH_ENABLE=Enable
export FTP_ENABLE=Enable
export IPTABLE_ENABLE=Disable
export TNODVB_ENABLE=Disable
export A42TK_ENABLE=Disable

export TNENV_APP_IFRAME_URL=/root/iframe/iframe.jpg
export TNENV_IMAGE_SIZE=1800
export dfb_evdev_rep_delay=1800
export dfb_evdev_rep_period=110

if [ -e "/usr/local/bin/sage/sage_bl.bin" ]; then 
    export SAGEBIN_PATH=/usr/local/bin/sage
fi

if [ -e /etc/settings/tv2next/3DTV.finger ]; then
    export TNENV_APP_3DTV_ENABLE=1
fi


export B_REFSW_BOXMODE=5


#QT4 settings
export QT_VERSION=4
export QWS_DISPLAY=directfb:width=1280:height=720:forcepremultiplied
export QT_PLUGIN_PATH=/usr/local/bin/Qt/plugins

if [ -e /root/fonts/qt/wqy-microhei.ttc ]; then
export QT_QWS_FONTDIR=/root/fonts/qt
export QT_QWS_FONTDIR=/root/fonts/qt
elif [ -e /webkit/fonts/wqy-microhei.ttc ]; then
export QT_QWS_FONTDIR=/webkit/fonts
else
export QT_QWS_FONTDIR=/opera/fonts
fi

export TNENV_APP_HDCP_RETRY_STATUS=1

export BLUETOOTH_ENABLE=Enable


export RF4CE_ENABLE=Enable
export RF4CE_EVAL_ENABLE=Enable
export RF_CHIP_NAME=GP502

4 执行 /etc/init.d 目录下的S*.sh脚本,以数字的大小顺序执行。

例如: 

S50_start_system_services.sh  

S60_start_nano_lamp.sh

<think>首先,用户的问题是关于Linux系统启动过程中sh脚本执行的先后顺序。我需要参考提供的引用信息来构建回答。 关键引用点: - 引用[1]:提到Linux启动时,/etc/rc.d/rc脚本根据运行级别执行/etc/rc.d/rcX.d/目录下的脚本,其中X是运行级别。脚本以K开头表示停止(stop),以S开头表示启动(start),执行顺序按数字从小到大。 - 引用[2]:补充了运行级别的概念,运行级0到6,常见的是2,3,4,5。init命令用于切换运行级,系统会执行对应目录下的脚本。 - 引用[3]:介绍了使用systemd服务文件来控制启动顺序,例如After和Requires选项来指定依赖。 - 引用[4]:是关于双击运行sh脚本的注意事项,与启动顺序无关,所以可能不相关。 用户的问题焦点在启动时sh脚本执行顺序,特别是在系统启动过程中。 系统启动过程: 1. BIOS/UEFI -> Bootloader (GRUB) -> Kernel init -> Systemd or SysV init -> Runlevels -> User scripts. 在传统SysV init系统中: - 运行级别定义在/etc/inittab中。 - 每个运行级别有对应的目录:/etc/rc.d/rcX.d/ 或 /etc/rcX.d/,其中X是运行级别(0-6)。 - 这些目录包含以K或S开头的符号链接,指向/etc/init.d/中的实际脚本。 - 启动时,系统执行S开头的脚本start参数,顺序按数字(如S01script, S02script等)。 - 停止时执行K开头的脚本以stop参数。 在现代系统中,systemd更常见: - systemd使用单元文件(.service)来控制服务启动。 - 启动顺序通过依赖关系指定,如After, Requires, Wants等。 - 用户可以使用systemd创建自定义服务来控制脚本启动顺序。 参考引用[3],它展示了如何创建systemd服务文件来控制启动顺序,例如指定After=network.target redis.service。 回答结构: 1. **介绍启动过程**:简要概述Linux启动过程,强调脚本执行阶段。 2. **传统SysV init系统**:解释运行级别和/etc/rcX.d/目录下的脚本执行顺序。 3. **现代systemd系统**:解释如何使用systemd管理启动顺序。 4. **用户自定义脚本**:如何添加自己的脚本并控制顺序。 5. **总结**:关键点。 确保回答清晰、逐步,并使用中文。 添加引用标识: - 在相关部分末尾添加[^1], [^2], [^3]。 生成相关问题: - 基于主题,生成3-4个相关问题,如如何添加启动脚本、优化启动顺序等。 最终回答结构: - 回答用户问题。 - §§相关问题§§ 部分。 现在,构建回答。</think>### Linux系统启动时sh脚本执行顺序Linux系统启动过程中,sh脚本执行顺序是系统初始化流程的关键部分,它决定了服务和应用程序的启动优先级。Linux启动过程大致分为几个阶段:BIOS/UEFI引导、Bootloader加载内核、内核初始化、init进程启动,最后是运行级别(runlevel)脚本执行。其中,sh脚本执行主要发生在运行级别阶段,具体顺序取决于系统的初始化系统(SysV init或systemd)。下面我将逐步解释执行顺序的原理和控制方法,确保回答基于真实可靠的Linux机制(如CentOS、Ubuntu等常见发行版)。 #### 1. **启动过程概述** Linux系统启动后,内核加载完成时,会启动第一个用户空间进程(通常是`init`或`systemd`)。这个进程负责执行初始化脚本: - 在传统SysV init系统中,脚本按运行级别组织。 - 在现代systemd系统中,脚本通过服务单元文件管理。 - 脚本执行顺序的核心原则是:数字编号小的先执行,依赖服务后启动。例如,网络服务通常先于应用程序启动。 #### 2. **传统SysV init系统的脚本执行顺序** 在SysV init系统(如较旧的CentOS或Debian版本)中,运行级别定义了系统状态(例如,运行级别3为多用户命令行模式,5为图形界面)。脚本执行顺序如下: - **运行级别目录**:每个运行级别对应一个目录,如`/etc/rc.d/rc3.d/`(运行级别3)。这些目录包含符号链接,指向`/etc/init.d/`中的实际脚本。 - **脚本命名规则**: - 以`S`开头的脚本(如`S10network`)表示启动(start),在系统启动执行。 - 以`K`开头的脚本(如`K20apache`)表示停止(kill),在系统关闭或切换运行级别时执行。 - **执行顺序**:系统按文件名中的数字从小到大顺序执行: - 例如,`S00sysstat`(系统统计工具)先于`S10network`(网络服务)执行,因为00 < 10。 - 所有脚本以`start`参数调用(如`/etc/init.d/network start`)。 - 这个过程由`/etc/rc.d/rc`脚本控制,它根据当前运行级别(定义在`/etc/inittab`中)调用对应目录的脚本[^1]。 - **示例流程**(运行级别3): 1. 系统加载运行级别3:`init 3`。 2. 执行`/etc/rc.d/rc3.d/`目录下的脚本:先`S00script1`,再`S10script2`,依此类推。 3. 数字顺序确保基础服务(如文件系统挂载)先于网络服务启动。 #### 3. **现代systemd系统的脚本执行顺序** 在systemd系统(如Ubuntu 18.04+或CentOS 7+)中,脚本执行更灵活,通过服务单元文件(`.service`)管理依赖关系: - **服务文件位置**:自定义脚本通常放在`/etc/systemd/system/`目录下。 - **控制顺序的关键选项**: - `After`:指定本脚本在哪些服务之后启动(如`After=network.target`表示网络就绪后才执行)。 - `Requires`或`Wants`:定义强依赖或弱依赖(如`Requires=redis.service`表示Redis失败则本脚本不启动)。 - 执行顺序由systemd自动解析依赖关系,不再依赖文件名数字。 - **添加自定义脚本的步骤**(以sh脚本为例): 1. 创建服务文件:`sudo vim /etc/systemd/system/myscript.service`。 2. 定义顺序依赖,例如: ```ini [Unit] Description=My Startup Script After=network.target redis.service # 在网路和Redis服务后启动 Requires=redis.service # 强依赖Redis [Service] Type=simple ExecStart=/path/to/your/script.sh # sh脚本的绝对路径 [Install] WantedBy=multi-user.target # 在命令行模式下启动 ``` 3. 赋予脚本权限:`chmod +x /path/to/your/script.sh`。 4. 启用并启动服务:`sudo systemctl enable myscript.service && sudo systemctl start myscript.service`。 - 此时,systemd会在启动时按`After`顺序执行脚本,确保依赖服务就绪[^3]。 - **systemd的优势**:支持并行启动,提高效率;可通过`systemd-analyze critical-chain`命令查看启动顺序链。 #### 4. **如何查看和修改脚本顺序** - **查看当前顺序**: - SysV init:运行`ls -l /etc/rc.d/rc3.d/`(替换3为当前运行级别),观察文件名数字。 - systemd:使用`systemctl list-dependencies multi-user.target`查看依赖树。 - **修改顺序**: - SysV init:使用`chkconfig`命令(如`chkconfig --level 3 scriptname on`)或手动重命名脚本文件(如将`S10script`改为`S05script`以提前执行)。 - systemd:编辑服务文件的`After`或`Before`选项,然后运行`sudo systemctl daemon-reload`。 - **注意**:错误修改可能导致启动失败;建议备份配置文件。系统脚本优先于用户脚本执行,用户自定义脚本应放在`/etc/`目录下[^2]。 #### 5. **总结关键点** - **顺序决定因素**:在SysV init中,文件名数字(如Sxx)决定顺序;在systemd中,依赖关系(如After)决定顺序。 - **典型顺序**:基础服务(如文件系统)→ 网络服务 → 应用程序。例如,网络脚本通常在数字10-20之间执行。 - **推荐实践**:现代系统优先使用systemd,它更可靠且易于调试;对于自定义脚本,通过服务文件精细控制顺序以避免冲突[^3]。 通过以上步骤,您可以精确控制Linux启动时sh脚本执行顺序。如果需要针对特定发行版(如Ubuntu或CentOS)的详细配置,可提供更多细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值