|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。' E6 f l) v& t
, k2 r" Y& T; ]8 _6 a4 d1.Login Items
6 b. K2 K* F2 o; p打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。5 D, [3 I6 A2 N" R( l8 Z: P
9 F$ _3 e8 `9 S& T- P* P; k/ B( L: s
; A8 _5 o7 ]9 R' U
2.StartupItems: \, R. D, h' i$ W) J& _) K
StartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
9 n6 }( e) w( m) D J( B V) \7 |. U& H) t. J! J1 w; d. l
StartupItems一般存放在以下两个路径下:
8 @" y2 p5 K. t* a
( I" ]( X- g M& l; I1)/System/Library/StartupItems3 b& k' k3 t$ }9 d0 I2 p9 \
( q$ i% g- [6 G! l
2)/Library/StartupItems8 o3 P/ m& `1 y/ ~+ a1 H' A
7 E! V& o. B6 _3 u' n' k* I G大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。
' R+ ~; q* f: Z" Z
* n: X) k+ m7 X; U) b这里我们以/Library/StartupItems目录下的IcebergControlTower为例。
. s% B9 s& H% n9 w }7 a* W4 }# \7 G
' J( Z# S5 d2 x, x" r9 S; j. d
6 O R B& m9 P y
. i& o) Z) B0 M: W1 u' }( ~& D简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:% d" B0 b4 |( b7 l: t
6 l% U0 G/ \* i1)可执行程序;
! Y; W5 \% j5 w. b: B# V' M8 D+ e, ` Q; p S7 Q
2)包含依赖进程关系的plist文件(StartupParameters.plist)。4 Y5 v9 w+ d) o1 Z7 i1 L4 Q+ b
5 X7 @2 V' q; ~& Q
2.1 The Property List
4 e9 P" c& o1 ?* c. i* J4 Y. d2.1.1 Plist的key值与含义1 O) S; @4 e# |% E: U
StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。
( n6 y& O, Z9 e% j" d' ]; ]. X: R' t, o4 b
3 H9 S3 o& g9 ]& H1 P! U9 T/ ?1 L
; I3 I+ H/ t0 P/ N0 u该plist需要获得root权限,包含了几个方面的内容:* u( [- b. ~1 V8 j7 j
6 H: _* R% T8 C! ^1 m2 D, b1 n1)Description;
, v3 _4 T# J+ J' s! B4 o1 m
A3 ^0 V9 m" Q b8 B+ B. b 对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。3 {+ R V5 U* {2 X- a* m6 A6 C$ S& J
2 e3 W" B e6 G& k2)Provides;; W! Y, O- V5 q# r5 ?. v9 u5 g7 o
% P1 H! k; z) F5 i 指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。
* b, a* w( G ?& a4 X" [ N/ U) y0 ~1 A- o- u2 ^) B
Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。2 k7 G5 V: w3 I: y" i
# O% h& H+ T: e0 x* Y) e
3)Uses;
$ E! j9 P( N3 f5 A
$ x- `( [3 g1 N7 i/ s! [; W. \ 指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
7 ~) G+ `3 s5 K: c3 j" l. Y: k p g4 @$ l5 g& O6 q; \0 B
4)OrderPreference;7 d( h5 F, N! G
; _ m" T" M- ^7 M- A, ?
指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。7 r* \+ v: J1 y+ p) F6 X
) I0 h" K0 R: H7 k4 o! g, ?/ m) l5)Messages。
4 m, K" f" _2 o) H/ E; Z
# w) g P* s6 Z& P2.1.2 创建一个StartupParameters.plist文件
+ [" [3 ~; T' j, \/ p+ k<?xml version="1.0" encoding="UTF-8"?>
- J- p/ r- z9 u) M3 @6 b, Z: S0 d<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
2 b, L3 |% a) c' _ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
. `+ M" m) u, g1 q; M# E<plist version="1.0">. S" Y" i! c; p+ W# N' T& t+ g# c
<dict>
- ~7 ~( Q% m) T: w2 r5 K2 E <key>Description</key>
7 T9 `3 I4 ]& e* k! z# W <string>Iceberg Control Tower Initilaization</string>( l( ^. ?4 @! M
<key>Provides</key>
+ U c8 o# c8 u7 ~ G) i$ }, r <array>
" E1 s7 ?- r9 [& ? <string>Iceberg Control Tower</string>
2 W: x, Z0 m2 ^: C1 ~ </array>
$ Y, x( E: j" Y7 i <key>Uses</key>! s/ g9 w( v- J
<array>
8 i- x; \) D% f- j0 x7 ? <string>Disks</string># D! U+ W! w) a2 `9 ]
</array>4 u0 J3 j' [+ U. z8 J% B
<key>OrderPreference</key>( i( h- [5 }5 N2 l
<string>None</string>
3 m o% H& ~) g</dict>6 m4 H5 \; Y: ^; _1 S* d
</plist>5 L: k9 T& `3 b w* g. T0 K
3 S. I8 n: w, D& Z. x % V! ~. |7 o5 N# b
. c/ H* S9 r) W* [9 U6 q* {+ c2.2 The Executable File, B5 q) @* w, K0 [$ y9 h3 z
注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。
0 L" s6 ]5 a/ X1 j9 n/ C! }+ |
! @3 D* {+ Q6 @4 c 2)操作可执行文件需要获得root权限。6 R9 L: Z% k! w( z# j7 T
% U% g. ?* }: Q* ` 3)可执行文件是一个shell脚本。( T/ Y1 V: U% a! X0 C
( ^& e8 n3 X% \4 `3 W
打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:
7 i' n: t+ n' N. i2 i1 s/ s4 S: j p" U& c1 t# h
2 U! [4 s. ]+ j" d+ z" Y) C
$ E% E3 l; w8 m# c8 [3 q# A+ g一般的可执行文件包含这样几个方面的内容:
8 X! g1 A' g% Q0 C e
- H- R5 S2 d$ X3 ^! m5 h/ K1)./etc/rc.common& K3 E0 ~ m' V* B7 @4 Y- t
' A) @6 T0 ^) YApple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。5 ` u0 B, w7 S% s) ]
% K. ?* E1 _; ]# j4 A) G1 u, `! h, K
2)StartService(), StopService(), RestartService()* u6 Y8 q0 l- X
& n% E/ ]- F% W( Z" C
当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。5 a+ t, J2 A! F; y6 R; L
8 u/ D: k+ S" O7 x参数含义:8 B2 ^8 _; U! O$ s: L
9 L6 s2 b+ t8 h! _: O- x* f4 Bstart:开机过程中开启服务;
! @! i. k3 k) u8 Z, O2 [2 ]& B9 ?0 M6 a! O- d
stop:关机过程中停止服务;2 X; g- d1 q6 d" L. k
8 O' i+ ~. w6 c) M
restart:在特定条件下重启服务。# F+ F S; C8 U0 I9 q0 h7 |
# T. e3 W2 [& B5 E3)RunService “$1”
+ Z Y& c- S$ D( S) E! ?9 u9 v: E9 S, d5 P, L% b- S9 T+ z- x* v
执行传递给该脚本的第一个参数指定的服务。
5 `7 J# ^2 h: X4 o# \3 J7 {0 W, c
1 X i9 ?! `: w3 ~# P( t& ?( s2 u“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。# m$ L* z0 r+ v! j
: b& ~5 a& _9 s" ?( o
3. Launchd Daemon$ f' l1 k3 ^: a) z( G
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。
$ i( K+ c3 B/ o# R6 L. |! k8 L' G0 p
采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。8 D/ D) r7 M w
+ W* X4 ~* G' ?9 y" j' N8 v
3.1 plist文件格式及每个字段的含义:$ j9 @9 k% E1 D7 T7 Q- w
$ H/ k# z" E. K: ]+ j; b) A+ G( y h; w/ d" R6 a
1)Label【required】
. R1 C2 S" G0 y k0 O+ e: f
7 z9 I4 {0 t# m( \+ x0 Y该项服务的名称。
- B* o, Z3 N1 r8 r& O
% [% {, ]6 x: O1 Y6 |2)OnDemand【optional】2 \7 i$ @& z% @. o- `4 q0 {$ P) V
$ s, A8 J8 M5 |10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。0 P( j; |, s& M0 J# P- q: @
6 P5 E$ [5 w2 z# q% |6 T3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】
1 F* l4 p& u2 l0 y/ j! p
; g6 a7 O* O% {1 W( k; s# b; a指定可执行文件的路径。5 ?) N* k; e/ |8 }3 x# n, { Z
* u' t) ?( v0 U! p; J- t
4)RunAtLoad【optional】
% g) K# r1 U% c+ \! u5 W Y. k! [. G6 E% S! y, H4 t! x
标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。 c1 l; W4 u5 A4 u
9 i7 g4 n. `0 e) |- d* @5)WorkingDirectory【optional】
7 e( b" [4 I% Y x% {) ^, [$ V F5 _* V: L6 ]
该key在开启可执行文件之前,指定当前工作目录的路径。* ~2 z; q' P) ?. s, B3 p
# |5 E O( V/ {0 j) v1 I6)KeepAlive【optional】
5 r2 A4 i+ @ \* J3 c5 ]7 ~, q1 x5 G5 C% B7 l; x& A+ J
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。
4 P+ J7 R7 ?6 l7 e% H# A: W1 I N4 r3 U7 X
3.2 创建一个plist文件:* [6 C; Y) U7 Y
<?xml version="1.0" encoding="UTF-8"?>$ K4 |% {5 f# F6 U% ?, p) h: n7 i
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 6 O, s; H. h3 f
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
j7 p: R: y& i3 d- s$ t R/ w" `<plist version="1.0">
' K$ V3 V) A( \( v' U# M1 o<dict>
7 r8 n$ v( j2 ]$ m' w5 j6 F <key>Label</key>
5 H' k7 |9 m6 L$ ~6 z <string>com.yourcompany.HSPA_USB_MODEM</string>
1 l( x; \# S, u <key>OnDemand</key>- T# r* N( x. H& p) M# Y
<false/>% q6 Y$ b# [9 Z) a. y+ \0 s- u: V
<key>Program</key>
$ H P c2 T7 z- }7 Z9 ] <string>/Application/HSPA USB MODEM.app/Running</string>
% v; ?5 w% n8 J+ U3 | <key>RunAtLoad</key>
+ ?6 @; E0 u. b1 g0 } <true/>
) S0 D7 s/ T" Z. Y* ` <key>WorkingDirectory</key>
% T$ {) x3 w1 g <string>/Application/HSPA USB MODEM.app</string>: ?9 \7 K$ [6 ?6 T1 x
</dict>
9 B% D; p; T( s% j, Q" O</plist>
7 b7 D1 S: y2 ?& c# ~7 J6 {4.三种方式的区别
0 d/ A8 z2 Q2 ?- p4 I初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。: Y ]; c9 N' ~" P3 t3 _% ]
' \) s# |! z& Q- I; C; E
总的来说,LoginItems 和StartupItems的区别较明显。+ O r9 v; `2 {2 V( m
4 v- A" \) N2 \# o a" l7 f Q5 M( H/ L: ]! O* H
对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。4 V/ [2 C3 H) R' F) v5 v2 ?
|
|