|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。
- p- j% `) |( R' X9 R) P) g& b/ ~* m( m9 L, z
1.Login Items
6 @0 B5 s# O$ T9 M打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。7 C( b/ d; m' d* }% s2 S2 n7 x4 M
" M7 S2 {+ K3 i
- v1 C" h @ T+ ~. A R+ X$ d
# K9 h- k0 [8 O8 Q2.StartupItems6 \4 p8 v$ C; o$ T8 \
StartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
! _# z# [8 C5 b. w9 k* r4 L
% ^; s3 J2 J3 O6 U' O: U" jStartupItems一般存放在以下两个路径下:" }, R1 _7 s1 p0 \3 B' P
8 {3 a+ {5 s2 b/ G1)/System/Library/StartupItems, G9 n) J9 [# R7 Y* S6 t
# T3 I! ^; n5 H& _- Q
2)/Library/StartupItems
6 u) ]7 p9 `6 d* m$ y7 ~' O+ p2 Z: h& `% [: w
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。; Q& l6 c6 r9 ], r) J/ C- D
5 E3 I% h8 E+ f# {6 ^3 m7 h+ U$ H这里我们以/Library/StartupItems目录下的IcebergControlTower为例。
" X1 ~+ j0 g, `$ {4 V, ]( J( \5 }8 ~3 @7 \: t/ ?
& O. A0 l' i0 v1 E7 a$ ]
: u2 i. [9 s: r6 Z简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:+ O8 D! {3 O0 f( C
' }! ^2 h0 o& h1 q* q9 E1)可执行程序;& A% V/ x8 t6 M& _
7 }$ ?2 N B7 V- n, E3 w P2)包含依赖进程关系的plist文件(StartupParameters.plist)。8 Y( m, u% S$ r( s$ u
1 m! [% ? G0 {/ u6 A2.1 The Property List: f! y( u( Q) Y$ x4 J1 w% W; D
2.1.1 Plist的key值与含义; K i1 f- R* E: e
StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。3 ]3 n5 S) U; a, L$ x& o2 V- E3 O
, A; }0 t% i ]; n; |
( O7 U$ [0 w; n3 r: n: E
# u$ n2 v% z$ t- E- q v
该plist需要获得root权限,包含了几个方面的内容:5 X4 m& [1 V* F7 m* \& r
p: K, X' a/ ^6 A$ K, C0 e
1)Description;# F" ]3 I2 c/ ?
/ Y9 h7 J# O- w# {' x
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
6 H. q- r0 L5 U/ ?6 R H/ ~' ?! x. v& r4 e& q o
2)Provides;
; z" W) a' R2 J2 x$ J8 j' Z3 N: \+ H D2 i. O7 j5 W; {" f
指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。
3 @, V* O' K" }* r
2 w1 U4 F6 q" k' ^* m Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。
5 a% {! J" L' P; K5 n. M! J3 Z6 I3 c* C6 \ l+ _
3)Uses;
, w3 ]' c0 e( G% G0 g8 F( v
. j8 y/ o. K/ B* ` 指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
# h0 k0 h) \- s/ B: g
0 \( L! A) H5 y4)OrderPreference;
/ x$ d# A7 X- S
2 j" ?7 Q8 y V* `7 _) g 指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。
$ S+ {" F; S6 q5 x6 @/ D. X
$ I4 _6 `! T. M0 _; x4 S0 p5)Messages。
! Y, _) ^1 Y) Y( P7 L8 S$ \' r0 q& s, F
2.1.2 创建一个StartupParameters.plist文件* h$ b8 a* z# L- [5 h
<?xml version="1.0" encoding="UTF-8"?>0 Z' a% c0 G1 C4 E$ y4 y, B
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" + _ g4 |7 n, N2 x/ o/ b9 `6 E4 R" I
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
% G w1 u& R u0 M0 l- a7 y$ g9 a<plist version="1.0">2 v. z5 t7 B) n: z0 L6 s
<dict>/ _1 | }! M; @% ]# E
<key>Description</key>! g( N6 o1 \1 i) H. {3 ]1 E
<string>Iceberg Control Tower Initilaization</string>
# p+ y, m" z) z' L7 A <key>Provides</key># T- {/ U$ t0 h9 k' R8 O
<array>
. C" G5 X& \4 f6 e <string>Iceberg Control Tower</string>/ f/ T0 U! s+ o% \7 u
</array>* B3 ~6 c$ u, E% T8 J* H
<key>Uses</key>3 h/ b. c* I- q7 m j
<array>
. c5 [% i$ P* ?3 { <string>Disks</string>
Y5 L6 u+ s2 G/ {; e8 V: u </array>9 h$ |8 r2 t" D6 k0 V# F
<key>OrderPreference</key>2 E" }: _$ G) B. j* \7 _
<string>None</string>* M! P# O6 w& E' z: {! p3 A8 m
</dict>8 e5 t0 b. \$ V" {; {; P
</plist>7 S0 O/ N, W0 ?4 u* y& ~- [, m
! _# g3 r9 }" l9 G
9 D) F" ]4 J9 A. B
9 m4 ~: W" Y I2 _
2.2 The Executable File
+ D8 ^9 s3 w, l& T注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。$ M# M6 k4 f% r+ D2 t
* s; m A: N' z6 k, j
2)操作可执行文件需要获得root权限。! E _3 m0 m! y0 g- g5 W
% C) Y, D; J5 v! E6 N) V 3)可执行文件是一个shell脚本。$ ?& K% G8 t2 N8 {. ^; j9 V
( |# a, P7 O2 X3 D- J5 m/ ~& [
打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:! Z! ]1 K4 a- }8 b
0 T0 k# k2 S; z( m: d1 o; I
3 Z& u/ x# w% W8 Q- l3 D" T
. A; _' m& b- U: }3 o- f一般的可执行文件包含这样几个方面的内容:
. n& R- r0 x# D3 L0 p) E, _) C J F( i+ B8 V) ~
1)./etc/rc.common
0 _0 ~9 A- [9 g) Z1 ]7 g5 ?
: l/ \7 U" C7 T2 b2 UApple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。
- G& M' h8 n ?$ @- H z! Y/ \7 g; `1 k# Z3 `
2)StartService(), StopService(), RestartService()
3 h, }: B W0 E& U5 n: ~* x6 W
) D) z& s/ B/ n3 s& D9 n1 C当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。
- o: L5 E: C9 Q
F& ~2 H6 G2 e9 W3 `, O参数含义:4 ?" }$ ~2 s3 z
- o. m7 o" ~6 A& J' M$ ?" _8 w) E
start:开机过程中开启服务;
5 b7 F9 B& u$ Q2 `% d! `+ R
" R# b7 \: v: j5 }* l K+ {stop:关机过程中停止服务;- V0 }$ j8 s$ E' f% K
$ _6 d( A- `. ~ ?restart:在特定条件下重启服务。
U# D, w3 L4 _1 M# e7 f8 w; k* h1 ^# @
3)RunService “$1”
$ R9 j' T m( A; p. T6 p1 ^( W" f" x! F; [
执行传递给该脚本的第一个参数指定的服务。
; x6 W9 k/ U9 c; ^5 d9 O9 h9 m6 ?! j. P. T, p/ S
“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。" x5 G0 K' k) l: p
' p/ L; k; X6 J2 v4 r; w* S3. Launchd Daemon' i. ~ Q7 s" Y3 u2 x3 @
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。1 }0 N$ s! ? q. |
+ m. v) E$ V8 V2 }
采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。
8 x; O. r. `" O' J
1 u& n: Y1 l4 j3.1 plist文件格式及每个字段的含义:
7 P( B B: p W' ~9 Z# W% }' E6 Z5 ^6 Q* x% C8 Q# u
- F& h$ i. G# y' v4 [& {. v
1)Label【required】
{' s5 C5 w) p, k. G- ?+ c9 k5 V3 u9 ]8 x4 F
该项服务的名称。
5 Q& g4 n1 A5 i, R. \4 i I ^/ b, @( T2 }7 f9 J5 g
2)OnDemand【optional】$ ]9 Z9 u" @ q u1 X
! ~3 K9 h2 ]3 T" g! L
10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。
& L" h% t" R( ]/ d' u* K F+ U- D O1 ?4 T# h
3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】/ [+ z0 \1 q' ^% U
# ]8 n7 _4 A" |8 C( b( V& A* o指定可执行文件的路径。, X# Q' d. Z* U: ~% l
8 w4 K1 c, |' {# P7 q4)RunAtLoad【optional】
* Y% f- X7 h" n& e; h
8 n0 r8 [' h# w& {标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。2 q# t" ]3 Z9 I) Y
+ K' S- f/ I8 C6 b" \ g
5)WorkingDirectory【optional】) Q% k& u1 c3 x. H* n( c0 m H
" U: E6 ]6 Z. X1 S; C2 N
该key在开启可执行文件之前,指定当前工作目录的路径。) v+ k) z' |2 m j
3 I0 W$ |& V4 E- }" ^* N9 @. j6)KeepAlive【optional】
4 B2 V! `6 h! b( m4 r' c4 |! [5 B2 ]" y( G0 @- Q* P Y4 D& G+ t
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。
- t% l$ \5 S6 z' x" n
" g D" x$ x' `$ n4 g3.2 创建一个plist文件:& p% Y8 ^: L% y
<?xml version="1.0" encoding="UTF-8"?>
4 e* a7 C6 k% v3 M& t<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
1 g0 l& p. q* ?6 h6 f "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
" \2 O8 H. |, b v" i# T' F<plist version="1.0">
% ~5 S5 s# ^! U1 E4 I<dict>1 | g7 r; C7 {$ X1 }- {
<key>Label</key>
( [8 q/ N1 S8 K5 E8 ?4 X9 w <string>com.yourcompany.HSPA_USB_MODEM</string>
* J9 H7 ]" M& }3 T <key>OnDemand</key>) P" H$ m$ L' K
<false/>
7 q1 a0 E$ y4 w <key>Program</key>. C" d% } B9 K8 N
<string>/Application/HSPA USB MODEM.app/Running</string>
1 a# a4 M B' N/ z+ M' [" p1 p <key>RunAtLoad</key>
' k5 Q2 Q3 n4 x1 a+ D7 l; O& l4 l7 W+ Y2 P <true/>8 J1 w1 o4 G2 [2 j2 Z3 p3 s# {
<key>WorkingDirectory</key>" ?3 ^9 r7 D: y
<string>/Application/HSPA USB MODEM.app</string>
4 f& a5 r* `" W7 O7 R! U</dict>) `6 ]% m1 ?6 h" X$ {* M
</plist>
9 f0 I- t8 V1 a+ v# r0 j# O2 O4.三种方式的区别, g( l2 h6 k* I
初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。( u/ p2 t# V' A0 e* P
, @( J1 z" o4 F. X8 J% M& m6 Y) X总的来说,LoginItems 和StartupItems的区别较明显。2 k: G4 @2 i- e* X0 F
3 Y6 s; u, F3 @2 J+ k
" U. K4 q7 v2 c对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。' k/ {) l; | c/ G2 K" W
|
|