|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。3 H' x1 b% W# _ ? D) W/ U
, j* Z8 K! f7 t7 l5 J0 v1.Login Items0 m! T) A0 K2 x, h5 O2 _
打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。4 D; s! M5 o- O8 a+ d( V
2 W5 M$ K" _5 U$ E/ I) B( ?
" T/ m" K$ [+ Y' ^: m" m* ^# C
0 ~( F" e& a/ A2.StartupItems9 r! v5 Z" ]& L" _
StartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
7 l& W( C+ ^1 J( t) W K/ |7 j& U- L8 j- `* X( ~% i; M! K9 x
StartupItems一般存放在以下两个路径下:
: J, z3 D5 J/ m+ x: r/ O2 B
$ R% l! Y* e1 ^- v6 T' h1)/System/Library/StartupItems# @) X1 H, v& \0 a; ]
0 N/ Z, C, @" X4 Z/ q, ~
2)/Library/StartupItems
/ L. i2 t$ P$ [- e" w' Z; V: h/ F& g4 \* \
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。
1 L+ V5 L4 a( G4 s% E: o! I/ }4 c/ M, L
这里我们以/Library/StartupItems目录下的IcebergControlTower为例。
9 {0 w0 D: W" B. O% q& j9 J0 S- l# C) {+ z+ z
$ M# p C0 }0 V S; d% t
- {) L0 h: ^% t1 r
简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:" A& p# z- S6 t7 S
2 s0 b, g: f1 A' ]& q' Y7 x) x; H1)可执行程序;: M1 R' q* u" `7 B) a$ W, M
8 o |. L) b7 B; o+ V) t+ _# O! O2)包含依赖进程关系的plist文件(StartupParameters.plist)。
8 b3 {' N+ \5 J
" B, g6 }( b3 l' M2.1 The Property List
8 p) x) |" X J j* m b8 D2.1.1 Plist的key值与含义
s& T/ {5 ~- f# z& CStartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。
/ g: K& Y9 y4 W$ i: J3 c5 s1 ?0 t, u8 b! ]- g" L
( ~+ ]' j2 b1 H6 S% l& L, T5 L
# Z1 S4 n; { W' J
该plist需要获得root权限,包含了几个方面的内容:" U* R2 g8 |: z* i. D
" q8 _4 a7 E' p6 g
1)Description;
: R9 J* p) `) n8 y Z. |: W! ]+ D5 }# U& B3 g3 S6 A. A
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
+ @% \9 q" A% W
; J' I# e0 J6 _% Z0 Y. H2)Provides;" A) t: [& X! w5 ?( @7 a
* Q* i8 R' i) |" n6 |- `4 d 指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。& ]. W/ I# _& x1 i
# {5 K( f+ a) f g' k$ P8 c: i Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。
3 \: H3 s( t/ K. {. a9 W8 N. V9 K ^- h# _7 f' h
3)Uses;" b+ w2 U2 {9 u `& l+ ^5 T; ?
# w% a0 W% ~; Y z7 Q9 y 指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。$ W" [% Q$ B$ S( N" ?
O, l2 u0 |5 Q7 p; z: Q. [
4)OrderPreference;
3 H6 a* A; F/ S0 v% M5 B$ m2 l8 _7 d: u* T) M" @! C
指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。
6 V* y: g P9 i4 s/ @& A9 L. Z. x1 [
5)Messages。
! V3 K( X" M, T4 E+ `
8 I) b" l# q3 H; S! y% ~2.1.2 创建一个StartupParameters.plist文件$ j d1 X2 v- K1 @
<?xml version="1.0" encoding="UTF-8"?># b1 N- U0 Z1 M! q5 G$ g# R* `3 m
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" - ?% ^# f* c# ^" E
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">0 p$ m4 H8 D5 W; O- Z
<plist version="1.0">
7 o5 z- l) k$ N& d<dict>
# i- M u8 N) `5 I4 h* _ J6 [ <key>Description</key>
' q$ S! H, d( f) k1 Z/ K <string>Iceberg Control Tower Initilaization</string>
* G: ~' z. [4 C( u1 M <key>Provides</key>
) P I; s& k1 ?- G8 X <array>& {5 g9 q# s% p: t- m: E/ u( E
<string>Iceberg Control Tower</string>
4 M; s h7 e0 q7 a4 K </array>) g, Q5 a$ h' V X( W3 _1 i$ y/ n6 B
<key>Uses</key>! i9 F6 e3 p9 o" i
<array>
# I9 \6 T2 B9 j: Y/ M3 i7 O# I9 Z <string>Disks</string>$ E( D J/ o( |2 c3 j- E
</array>
z- R! u/ i5 O; u& @ <key>OrderPreference</key>
- F2 Y" |. a6 C# r% q' |8 Y <string>None</string>9 v/ u- N% ^* `* g
</dict>
. T. x, Q# C4 N- }9 Q</plist>
' ~# _1 Q. ^7 T* L- v
" s- c" z% H) {6 A9 W
+ X" T/ t' d# {+ Z8 O& k, J: Z- f# B* g& X f0 N+ H
2.2 The Executable File3 B- v- N# w3 g% b- W0 ^- S
注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。% @. N; z8 g( B% D; \- h7 s
$ I, J7 s V9 n8 _* m! P 2)操作可执行文件需要获得root权限。9 b4 s$ V% F. o. d9 ], A; ~
" M A+ i& v" b$ F. e, z 3)可执行文件是一个shell脚本。
8 T5 X M$ x3 Y, r: i- Z8 L1 ]
* b: O4 h- S& H+ _打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:
7 l) `5 G0 j* q8 u* L3 K/ \. w0 \8 J( g$ h
4 b k9 B/ T7 J3 w5 m+ H
4 B( Y( Q3 q, i9 Y7 c5 w
一般的可执行文件包含这样几个方面的内容:
' V+ V( s8 }, F F: o
* T' Q( ?( _4 D5 l1)./etc/rc.common
" k) Y2 E. ~' ~# X: v
& H. P0 l; P3 t* W: kApple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。
5 I& n# X. w' C5 j
N. }8 l- U# T, ?0 B2)StartService(), StopService(), RestartService()7 r& i4 \2 ^6 f% p; j
p! V5 s8 c, U; {, |+ V; {6 V当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。5 y, Z+ ~* N4 j& B
' B3 Q: M" X+ n8 @
参数含义:7 U: w) z' x Q: s3 |
* Z6 `- w1 _9 E/ h3 I4 a# w0 M
start:开机过程中开启服务;8 X% j1 c" t& `( I/ ` l7 T' ?/ Z
3 d% a9 y, N/ w' ?7 e) u
stop:关机过程中停止服务;( f8 g$ d. A4 C, T; ~
2 V& S4 @+ U+ ^" v0 srestart:在特定条件下重启服务。
' S* v ^# v$ f3 V" I! |( F; X+ M# { o5 X' l$ g
3)RunService “$1”/ }0 s) C! f) j4 X9 `; O S$ L* X
0 n: }1 l! v" w# L执行传递给该脚本的第一个参数指定的服务。
9 H ^/ D9 d5 @2 c
, T7 n6 E8 `0 z, V! |" L6 D+ J, h“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。
5 H `, `5 M2 o9 m8 D3 b! Z
- y! F/ u8 ~& t% ?7 K# E7 O0 N4 ?8 M e3. Launchd Daemon
* ]6 R6 n% ~4 `" nlaunchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。, m6 J9 ?1 Y; S# W9 ]2 r. n* T
/ I8 w$ O% H- E+ ~/ u. ]采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。7 X" u2 q- H. A9 F7 ]
3 Y: \7 x5 D4 U3 a3.1 plist文件格式及每个字段的含义:
* N2 i2 E2 s) K: M7 A. e. G1 `- J& L! K8 j$ T% L% w4 |9 G* z5 P
$ o% h- G8 j0 h! N1)Label【required】$ O; l! U9 J' ^! V: E2 Z+ N
0 w7 `: Q- S! j2 S1 {9 J
该项服务的名称。
' e0 L+ H1 B" A( m
4 U _1 I; g5 G% N5 L+ R2)OnDemand【optional】
7 o& r: `: r% o# J5 D% |" @, k, l1 A6 |$ i7 r
10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。
) \# T3 g- g5 X+ y8 M) }) L# _: F$ ^! V- }6 y. w+ R
3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】
2 e9 y# F: W) }2 y. W
. s' N! f, E5 o3 r# |) H' L4 r F" L指定可执行文件的路径。
* o: q* C0 M3 e# i9 O2 _: x5 {1 h$ m1 p2 I0 a
4)RunAtLoad【optional】
$ f7 A, ]# ?- t6 o9 @8 H# k
4 e% s) _. t) H+ t$ J2 @! a, r6 E0 p标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。
' j% T& N2 {; c8 b4 J
2 w$ s5 H2 h% a$ ^3 |9 n1 N5)WorkingDirectory【optional】, n" L# v3 B, v1 j
" @% z% V3 |5 }. m; G/ y$ W该key在开启可执行文件之前,指定当前工作目录的路径。5 x; V+ H& ?+ [# |( @
e$ K! V, h. {# a6)KeepAlive【optional】. Y9 s! o: Z$ r- A6 l6 l+ s" N
# h4 A9 w- D) N& O+ R+ n
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。6 t; z% f; ^0 i
$ A3 v* y/ d# M! G! {3.2 创建一个plist文件:6 W0 U7 ?* j! F( O; p/ c/ N
<?xml version="1.0" encoding="UTF-8"?>
, M" z, h, Z ~8 X5 R<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
" }( w* ~3 G( S& ]. @) A "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
5 @6 Z2 ]6 U( @5 p- O) ~<plist version="1.0">
. W6 ^! z; y8 {; o<dict>% h+ u. ?0 O T) y8 j9 l$ {7 W9 S
<key>Label</key>) {) [3 N; Q7 p' L
<string>com.yourcompany.HSPA_USB_MODEM</string>: _; U# Y- s. o4 t* P
<key>OnDemand</key>
9 X" T# _ p: r- |1 i* j* n <false/>
- M8 U! l3 R ]: L- ~ <key>Program</key>
S G, n: s/ p* C4 `3 S <string>/Application/HSPA USB MODEM.app/Running</string>! a0 U! c$ u7 E8 n
<key>RunAtLoad</key>& u3 L$ ^& C3 e
<true/>
& F9 D/ w6 J' c) ? <key>WorkingDirectory</key>
2 q b, }8 k4 N7 W& x3 ~; O. ? <string>/Application/HSPA USB MODEM.app</string>
; \/ ?; e9 a' ]5 T( `</dict> F# Y" c' f- U a! c& X% J& x- g
</plist>
" L6 H( H6 m5 k- I# `' v4.三种方式的区别 N" j0 k* ]* m3 Z9 ^
初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。% n: A, C) R* \
; W2 C+ y& ^* r/ S+ h总的来说,LoginItems 和StartupItems的区别较明显。0 p* e6 b' B, X4 i# h
4 i# R) Q9 x0 X/ }2 k3 M7 u& Y$ `
对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。
& w3 H' ^0 o) O0 A" ^" C. C5 @ |
|