|
|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。 g: Z% a7 K: y* w+ w8 m
" q% D ?7 A/ B: o0 B. Z1.Login Items
# I2 l4 H, }3 Y& d! `打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。6 n2 ? b) T8 y
% j! T( \. V8 O s3 a$ o, i) e4 s2 A7 r
2 ^- K; B3 Q) C8 J3 i( _0 V2.StartupItems e5 R0 m& C* I2 r! [
StartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
6 N2 W: E) O1 ^$ F. s, [4 x. |4 {9 U4 O {; M. j E
StartupItems一般存放在以下两个路径下:' `6 x+ H, t/ N6 R9 C
8 U8 [( T y; m: N' b1 A8 w/ @1)/System/Library/StartupItems8 r$ w0 M) C. A/ P5 e+ s
9 C$ W( L+ _# X3 `: r' S
2)/Library/StartupItems
8 t% w. n- ^4 w$ d2 d% h& z( w# ]8 Q/ q l( X Q
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。( W# K2 h. ~( u
Y5 W) ~; ?/ m* A+ [! i
这里我们以/Library/StartupItems目录下的IcebergControlTower为例。
! Z# t' M+ J, H: F; w4 G
$ S: |6 T. h, C* I% C. K1 O( X+ M" X* J3 I
3 ]* j, S4 ?2 A; Q3 F7 X
简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:
" B; m7 U+ c q0 |7 U) I$ S+ m- T* t I% j0 u1 s
1)可执行程序;
0 b. J# I% {6 _/ v% y& l. B! s
. V# V j0 h* `" t. B2 U2)包含依赖进程关系的plist文件(StartupParameters.plist)。( _2 H; V, h2 I( D0 j: B k, ~8 R
8 E7 V. P3 s+ M2.1 The Property List% S* h- Y* B2 N D
2.1.1 Plist的key值与含义 E# ~4 {) L3 d ]9 o# O
StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。3 F2 w7 |1 ?0 U$ K5 K- v
1 _- h( E! s9 r* I/ _$ p2 M, i' ^! |6 `& K3 W
0 T7 V9 L5 A! _( A* Q% `) v
该plist需要获得root权限,包含了几个方面的内容:
; }: y* l3 ]# b$ z( O$ T. p: q2 [& S
1)Description;
* u g* ~6 h1 O! |5 p! ^$ C* |1 s5 _1 ^/ I
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
, t$ ~. c5 R, J- N0 A! ^- Z
, }, a! U; A7 J- @2)Provides;+ l. Z1 Z$ G, z
9 i, q) Y, L8 _* b j0 f
指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。
! \/ ]$ p9 A" `0 p
- f& \4 ]- p4 b* K% D Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。
v7 t! d7 L, o% g
7 ?0 I) z, U+ {: W: H3)Uses;. l2 m6 P0 n2 G+ r1 J' I! X+ k
& T1 y5 t2 g! V. }$ f! N, r1 E 指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
3 H- U" [/ B& ?1 Y; Y! P* H$ R2 o2 x/ n( c
4)OrderPreference;& \- r, Y& B$ E5 t3 y0 C+ t' u# f
_( F3 F, M+ M6 ^0 V+ Z) T, e0 n 指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。
- n6 Z9 a8 m/ R
. T1 f2 |7 B* ?$ }2 C5)Messages。+ k$ \3 ?; |0 ^# k
! A" Y6 }" g& g# o9 S9 S
2.1.2 创建一个StartupParameters.plist文件& I- m* w1 o4 C7 f2 \. c+ e
<?xml version="1.0" encoding="UTF-8"?>
8 v& x& T/ _' n! M' }5 D U, ^<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" $ m3 f9 U" ^: U. u- W
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
8 r; E$ v* s- q. W' j8 m<plist version="1.0">/ z0 }9 p3 g* k/ h+ h
<dict>
' n! ^" H5 ]6 S/ c1 }. R9 _. K! C <key>Description</key>% l7 h: W h( ~
<string>Iceberg Control Tower Initilaization</string>
. c7 ~; y8 k/ n3 a/ l <key>Provides</key>4 {* o6 @- d- \9 |
<array>2 G' J! J' l6 V! [
<string>Iceberg Control Tower</string>
8 ^. X- A5 ?: h2 d1 h3 V) z3 v </array>
6 {1 Z1 ]5 e( P# j9 v <key>Uses</key>1 }7 k1 U2 u. W6 n
<array>
7 Z( c# g4 v- Z) d <string>Disks</string>, N5 |9 {( O% S. L) j# T# {7 f
</array>, {4 _6 h. H! i2 Q# T- i3 ~
<key>OrderPreference</key>
9 Y5 p. M: I* }- v4 m- v* L <string>None</string>9 _" H- K u/ l, z
</dict>
0 Y* j9 ^. C! ^$ A% F</plist>
* N4 ]2 n8 R$ U5 F9 I3 ?- C- i" ?% q; d
. ^, S4 u, p+ I! q/ C! F, }* f. N; [2 Q" Q, F9 E+ Q' U
2.2 The Executable File
3 n- e9 J% e7 s% K, R. F! ?注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。; A; J' c: L# Z( Y
! d5 U4 @. a7 r' _0 v) T( @
2)操作可执行文件需要获得root权限。
6 ^1 }6 U W) |8 w% ?, ~! L% p( I) p: ~
3)可执行文件是一个shell脚本。2 S r; B0 ~/ u5 R1 Z3 ?3 \' }
& e: W6 {3 @6 `, M. W+ j
打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:% V; @4 g- B3 A- m- `
3 B: C0 I" g6 O: f9 E! E
$ h# M, |, P' k( y3 e
7 n1 |) K8 p7 o0 n
一般的可执行文件包含这样几个方面的内容:. r0 A, ]! g, E/ @5 e! b8 G
9 v2 F& Z* J1 I( ?8 J0 z! |
1)./etc/rc.common, x, O7 P7 d) Y* Q8 m/ P
& a2 ~9 G. T& D6 f/ l1 S" z6 f3 QApple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。4 I/ i8 B) c% U: v
! \5 R/ E! R, Z1 V
2)StartService(), StopService(), RestartService() |5 w' o7 f. K
; `1 i0 j; N9 g8 B( f( Q- S/ k当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。
$ R7 C' g, H& T4 L6 f3 g `
1 G! i2 h/ ?8 h: N0 M参数含义:# t' y. \- n& i w- Z8 o3 \+ T0 x
& j6 Y1 e% R0 A s
start:开机过程中开启服务;
0 u; K" Z6 U8 s, h
8 U- x: T: r% v; Z4 u) x8 Mstop:关机过程中停止服务;
. T; N$ _2 {# i1 @3 m" d, n5 ~9 l2 V% E1 l3 [
restart:在特定条件下重启服务。
; A+ R7 Z, w/ ^* ^! Q: p6 l* E6 H' L- Z/ |) Z( j. c
3)RunService “$1”
# A/ I8 w4 _' [: ]; f) C1 I
2 S5 y4 L1 L3 l+ `5 W5 \0 T执行传递给该脚本的第一个参数指定的服务。
: b8 W8 u1 V2 o2 N& k7 m+ k' p, h: G+ l" B
“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。
1 F, _8 x( i! H1 d5 S
+ o& B5 t6 F5 _% c' E* V& }2 `3. Launchd Daemon+ \( ^% i0 T4 w; l9 M5 g* M+ d5 [9 ]( e
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。
, ^8 t1 c# Q0 W0 E, e
0 \& K9 j, C2 @4 T8 d3 O) P采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。" r8 x+ M- ?( F* u
3 J) L3 f7 G% T. Q9 I
3.1 plist文件格式及每个字段的含义:
, _2 o+ f% o7 Y) h: ?: b0 X2 {, u; R: ^% |" J
( z3 E. u% @( I$ A* y. k1)Label【required】2 Q' n1 S+ P1 u
4 H% ^* e# Z! U# G
该项服务的名称。
6 i5 I2 h4 A: p! K! V D
& u, ]% R$ n; C6 r6 V( o) R2)OnDemand【optional】
! l: o( N' x% C0 r' r
5 J- v, i. f* M4 @0 ?1 H& C: _10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。' u/ B1 p* Y9 U% z7 b, G% N
- k& `% j8 H1 x) ~
3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】% ` O# n1 [" H* i& |- _9 e, R
+ A3 F$ b' M6 n$ N指定可执行文件的路径。- o1 R7 E) U+ C0 L/ P
6 r3 X9 k8 V: @6 F; I
4)RunAtLoad【optional】: ?& l; F6 Y3 G& l
# t7 W& @8 A. q5 C$ S x$ R# F5 J9 Y/ Y
标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。
g5 V! {: y1 w* \8 E3 M, F/ L* }. t5 D+ ], }& u) @# R! c, s
5)WorkingDirectory【optional】
* t" A% X! r# V6 a2 G+ g; C9 k; P8 F% O4 c
该key在开启可执行文件之前,指定当前工作目录的路径。4 y; {( Y" c r v z) D+ A% g# K
1 U7 U5 A+ f7 e" @! ]& q O6)KeepAlive【optional】$ r1 v/ }0 ?' U
7 f, Q+ C1 h) h- I$ r这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。 T' ^; j2 B3 n P
- a0 d3 L! a& C. n& z: X' Q3.2 创建一个plist文件:2 r" \! m2 ^/ b! @
<?xml version="1.0" encoding="UTF-8"?>
6 t; [6 S! \! _- j" d<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" , C! F* `: c+ R) Q; B
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
( }# x" ? m! f<plist version="1.0">
3 d! n0 E/ `( o( W2 i2 u' G<dict>. ^% \5 e0 c/ u
<key>Label</key>, u% n5 o4 _2 L5 T4 x$ B! q) e
<string>com.yourcompany.HSPA_USB_MODEM</string>
6 R9 W; e( q& \0 O <key>OnDemand</key>% H- L) l) Y( z8 s/ J1 N2 B& Q
<false/>. a0 T% n) I2 C! o" B, G
<key>Program</key>
# w& ]* \$ U# n$ O! _ E <string>/Application/HSPA USB MODEM.app/Running</string>2 Q; Q9 T( y7 N( I$ [+ T
<key>RunAtLoad</key>
3 q+ A/ d/ l* |( F1 L- q1 X9 M9 w <true/>! v# _' j4 }7 L: m% c
<key>WorkingDirectory</key>
3 x$ N9 @) }; a- _. V L Z; b <string>/Application/HSPA USB MODEM.app</string>) g9 B5 K; e& ?0 m
</dict>" K$ f" e$ m0 W4 }8 x2 f0 d* O
</plist>
# ?9 d: ]1 u2 Q8 T5 t4.三种方式的区别4 M; t# F9 j; I1 J) X
初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。6 }( G o/ d% M% [' G5 r
2 S1 J9 D' k# q! a总的来说,LoginItems 和StartupItems的区别较明显。
, ?* A. r5 p& u
+ D. o) q3 s4 j3 x: r' y
# Y9 l6 Q: S4 G) j! T& I对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。
1 |: `$ @6 F+ R$ h' K8 }* @ |
|