|
|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。# D! ]* g6 {5 x! G" w
! I0 n# b, t8 Y* i2 ?
1.Login Items5 S% i1 d: u: l" c5 W6 T
打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。 j- b2 S8 x. j
0 s, z& a) n2 W+ _7 n0 X
* G) N4 i+ \; F/ j/ K5 T
) a+ e: v3 ]0 [' B' i- U2 C2.StartupItems
) j% E/ ^% t6 @* DStartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
, g& H, L6 ~$ T
; z7 }2 [" \" M& U- ^( O& jStartupItems一般存放在以下两个路径下:- b8 |8 A( D0 O; i+ q
8 q9 I5 p; j. R1)/System/Library/StartupItems
; A( c7 r/ f$ I/ e/ D3 h6 {7 W
( r$ V3 }2 n8 W5 j3 _; ~, `3 h2)/Library/StartupItems
9 f, v0 M4 n' B! P. C/ D9 W* c% l/ u3 i- z& @/ S
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。
( b) l/ e) n1 ~
7 h6 T% O. _& w3 C这里我们以/Library/StartupItems目录下的IcebergControlTower为例。' u/ l! n& _2 n% |# x7 e
2 _9 l3 l5 q; r4 f* M6 [; ]5 r6 G) v; ?0 H4 R
" f6 S+ G, x! m% m% j! A简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:
1 H7 A- ]0 O; A: j6 E+ u5 ?
2 C- ^2 J, d V1)可执行程序;
- V/ ?; v7 A' x* O! L) J2 e) [- q" h& W% }: ]& v l
2)包含依赖进程关系的plist文件(StartupParameters.plist)。" N' o, _ ^! \. I4 e
5 P8 n! u# K3 d2 U A2.1 The Property List
, z+ N: B3 O( Z& \$ T- w2.1.1 Plist的key值与含义4 }0 K7 s' l0 r% {
StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。
4 S1 J( Q, M% F6 ?3 X
- }- m# |2 P( L5 X9 g9 |
; U$ G! U9 G4 s4 ]4 w5 D# E3 J0 r* l/ S- F
该plist需要获得root权限,包含了几个方面的内容:, c9 |8 P9 B: q0 m- z
% p: r# A0 u% d; J0 O/ d- K( g
1)Description;8 a6 Y; p" Q4 v
2 @; p, B2 x; z. w; Y
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
: ?" N; z! Q4 n# A& Q2 |+ J* T
2)Provides;
f+ q4 q# j# a% l! H3 ?6 z+ w) ^. p% z3 s
指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。
' K* \3 d4 l% E( }5 ^1 v3 c& h. c3 @' x. z" g) ]
Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。
6 r) l( F/ M8 F1 p, U/ p3 g. G F+ X5 r& F
3)Uses;
. L) H. Z7 r: R. M/ {& o* S- k$ X4 K! b" \# Y
指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。$ H, R: q# c( M5 e) Y' R. L( ~
5 b& a2 Y, M* N; @; P3 \ S5 ~4)OrderPreference;' w5 M" \2 w( w
9 ?0 \3 e9 z7 h9 A9 | 指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。2 X9 {& H+ V) Q+ V8 u9 W
* s& K9 C! |+ _* F
5)Messages。
9 V5 T/ |5 f5 C* O+ g+ H- Q5 O% A6 C* Z3 Q& K% m
2.1.2 创建一个StartupParameters.plist文件
7 y) U( k; W0 x R- h$ T7 q- I1 X<?xml version="1.0" encoding="UTF-8"?>* _+ y- M6 \1 H- ~/ P
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" $ w y1 }& D3 Q' G6 S
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
' w! K; h8 a* Y& u<plist version="1.0">
& A' _ p$ b# p; X0 q' u8 ]- c<dict>8 b# G! z) U! {$ U7 a, Z
<key>Description</key>
4 D* i0 M. X, }& b6 r* z1 |7 k: w7 T <string>Iceberg Control Tower Initilaization</string>! ?) ?* x* |4 [5 j
<key>Provides</key>
; j/ A9 \! [! A <array>
$ Q* p& i+ m c( l8 U% V6 ]* G <string>Iceberg Control Tower</string>& E' g2 W' y, w* l7 P9 {
</array>
0 M6 e8 P% ]4 K5 Z <key>Uses</key>, f( N* {( C r6 }4 X' e
<array>
4 j% J) U8 }1 j( h& W& V; j* n <string>Disks</string># {. A, n& d1 q5 r
</array>3 F* V ]( ~+ [8 M: |
<key>OrderPreference</key>8 x4 E3 z2 `4 H$ a; E
<string>None</string>; p7 U C4 ?, O( g m6 v
</dict>; x5 H/ _* N: `
</plist>/ n! ` N' U$ j) L% _
1 r! L2 V; t) g
; o0 D; X" W8 v+ f; J
6 |! z' K# P) ~1 Y2.2 The Executable File# e. R }9 B1 D( |: r3 n) [/ z
注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。
) @! k/ X8 p y8 Y3 T
5 J& f; H1 m( ^/ K 2)操作可执行文件需要获得root权限。/ j& J2 D; Z# O! V: q) J
5 _8 I7 U5 ?- O, w( F% ?
3)可执行文件是一个shell脚本。
S9 K$ H1 g/ B2 c- Y9 L
% F/ t1 r# f+ z: z8 u! X$ ^2 a5 S打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:# u4 v7 d- G' \! S
8 I+ T9 W; s% V- H7 E6 ?3 J& W9 i' ?
7 \& w' Z/ _: X9 M/ U一般的可执行文件包含这样几个方面的内容:2 k* m& h! [2 r% P5 U4 a q+ K4 n
( w# z* x' Y) \8 _9 [
1)./etc/rc.common) m y- o$ c- t) R4 m+ F! w
o* i: {# e3 k1 y
Apple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。$ P" \. L! ^& ~8 P
, u& N, J5 m0 @# E5 u2 E$ u4 x
2)StartService(), StopService(), RestartService() ^$ o0 D/ B, |, I
& r9 I8 O4 S# v8 Q# y
当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。 k3 m, K+ _0 X
7 D9 e0 ~* r' S7 w% T' p: X& b& b4 K参数含义:
7 B& ], m* V# o- v( J* d$ @; y: j3 x4 b: m; K
start:开机过程中开启服务;% N/ q! D1 A0 p0 H; h) }0 o( X% J, {
' m/ \) e2 D% L4 \( k; a5 t
stop:关机过程中停止服务;
4 ?( y. N0 Y! c7 Z* }
( C3 H6 H: q. i5 {4 Mrestart:在特定条件下重启服务。' v: L. m: p: w9 h. h
$ r. o5 L( q. L8 K8 G
3)RunService “$1”
, A$ C Q* a9 e2 ?, O4 i# ]5 d
q' L: f# z( h9 s7 u执行传递给该脚本的第一个参数指定的服务。
* [. U3 n, k( d9 i! d. [, w4 x2 H* L. V( L
“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。
5 j/ G" E9 z7 [ ?) q6 q- y
6 C) I! N6 L9 q4 c3 F2 w3. Launchd Daemon
0 t5 p1 ^/ U$ Z6 p6 flaunchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。- w" d9 o& Q" j! L6 Y# n
& f! t6 G5 {! V: w4 R) Q* T采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。8 k# E; [- V+ U2 R! ~4 I
2 f2 r" U5 B# l# o3 X4 p2 W) A7 r
3.1 plist文件格式及每个字段的含义:! w c8 a8 s; @% h9 w! H2 }* V. ~7 h
1 w+ s; T$ O! |4 J
# h4 k/ y' L: G' w1)Label【required】6 s- ~* s$ g8 _1 N
1 g. ]5 ?. H6 o1 r3 x) y& J
该项服务的名称。& d6 O3 Y! K& f6 ^- w: K
3 ^% J( x T/ J6 P" P2)OnDemand【optional】
! L9 V, i) V2 \( P3 h6 b6 t9 y% L
10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。; ]' X* j2 Z$ B! S' x, ^* y
3 U/ c9 S$ O( f' }& o) P9 T9 m3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】$ M+ S- b) I; E5 b7 G' H
. w& m2 K+ q* \/ o. S: q1 ]
指定可执行文件的路径。) N6 j; I+ i+ G" h$ l8 t; J* e
% |5 D! E. s6 \' x) |, U4)RunAtLoad【optional】$ {( e( k d( `8 i; |% J
+ A9 q6 ~3 c! D3 u }
标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。) N! n9 n/ p, D$ E0 a
& A' B( d( q% B2 o1 w1 ?) h9 a+ f
5)WorkingDirectory【optional】. a) r }% P' l7 _$ B
2 Y# m+ H H4 K该key在开启可执行文件之前,指定当前工作目录的路径。
3 G) [& J7 q/ {' z
. ^& a: p% ?; q; ?, ]6)KeepAlive【optional】
) m, L" |* {9 m4 D! t* V* X/ @0 r; X5 ~. l: R1 v# p
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。
: B% x$ X# n- o' J; q. ^0 ]) U6 K: U
3.2 创建一个plist文件:( X) |! n/ @, b, ]5 `$ o) N
<?xml version="1.0" encoding="UTF-8"?>
1 ~' i% @, X, H4 F3 H. Y& d& K<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" : d6 M+ p: m4 G% D+ D
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
# L1 k5 V- Y- a9 D<plist version="1.0">
) b6 g$ B# C6 Y+ \2 N) h<dict>
: R( A1 b; Q' U5 R- c* J' U <key>Label</key>
/ ]6 M0 ^" j0 A8 s* Y <string>com.yourcompany.HSPA_USB_MODEM</string>
* I+ L' [8 E, o7 P4 z1 G( I <key>OnDemand</key>
3 x, g' s) x& u0 t8 j <false/>
8 L: B' _) O, m. G" h8 ~ <key>Program</key>
7 Y9 X* r) H. m& V; d" c0 a" j. q <string>/Application/HSPA USB MODEM.app/Running</string>
; P* K; [5 z0 _% w3 f1 k. W <key>RunAtLoad</key>
7 m8 F' b# ~: f3 E- `) X- H: c <true/>
% z! b9 B2 P. |/ }+ m( u <key>WorkingDirectory</key>
# `- d) C) g0 w* A! G& u: \" r <string>/Application/HSPA USB MODEM.app</string>& }$ ?3 d9 R* ]1 R
</dict>
5 _1 H+ O. c3 r</plist>* ?: x! [$ G& u5 U. V
4.三种方式的区别3 [- M& L- a6 z" N3 c. N8 N
初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。
3 p5 @: Z. T: N; b' G4 ~6 }( X, T/ \( q p
总的来说,LoginItems 和StartupItems的区别较明显。
, q& u$ n" j! N4 c- P8 `! W/ J
l8 G% e" u, V- j
, D' {. g# M1 i& S9 u对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。
+ o% W& }' X7 J; \9 `2 i: c# j |
|