|
|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。1 m1 H7 s1 X4 G d; j z0 B
. w' j" T2 y; {# a8 |& p/ \' v; h: @1.Login Items
, |4 h5 B/ B* ~' z5 |* _' x打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。
3 @! k$ ?* ~& }) G: M# _- m! \* K
- p4 h V& M c0 e; M7 X7 }% `6 X- ?0 G4 C
- P, @* J1 ?5 Q* ^2.StartupItems
5 a, S" ^' V- s: ?# E9 ?! hStartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。5 T7 W- |) f1 m6 a8 U
8 o! j% [% X4 I6 M5 Y( a
StartupItems一般存放在以下两个路径下:, U- I" M! w% _! q
2 B0 U& Y. ]" V( S/ ]1)/System/Library/StartupItems* q3 g' |' W# ]; e
+ ~$ g, P- W' j
2)/Library/StartupItems
. ~6 u* U' z% k& i" D& Q6 G
( \) J% |" c" J/ E, g, O5 ^' M大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。
2 z% M- |: y; D4 Q, J* e) c" D% ]5 k4 l0 y
这里我们以/Library/StartupItems目录下的IcebergControlTower为例。+ j5 _' h3 T& ^# k2 i
9 N* k+ s9 F# X" B% Y# S) Q
, N% @, Q# ]0 o' {8 r+ I" [
, c( P6 p5 k: h) Q, \简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:
) A. t% W- ~2 T9 c. O* `6 d# {! {$ w
1)可执行程序;2 Q& H, P. ? A/ @$ _
" \6 a: e( C3 o0 w0 l2)包含依赖进程关系的plist文件(StartupParameters.plist)。/ q0 j: N2 {9 n. j/ U. E# w, Z
2 t- k! f5 K' w" `0 q: \2.1 The Property List
6 `5 r- A2 j- V. h3 ]! |2.1.1 Plist的key值与含义
. ?1 [7 D/ N; T7 sStartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。$ u. J [0 _& F6 j- X( j
& B- j! G, v+ B
; O d* j8 G) q5 l9 T ^ D& Q4 s C1 j3 f
该plist需要获得root权限,包含了几个方面的内容:
, ~' Q% J/ _! E, _, \7 r {
8 ~, g8 S [; r' v1)Description;
, J6 m% L) |: n; {* x/ X" |; B
* @: Z3 n% e" V1 @# p( [) r& s1 ` 对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
) h9 A& K: j1 r* [2 _. L- f5 H* Q2 }/ S e7 d9 r$ \
2)Provides;
. d! O4 H9 t4 X/ [0 ~' r" f+ j5 N: ~& _$ ^4 z; g2 i- E
指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。' u7 r' P# A9 d6 V9 Z& n
; b. M! _. Q$ ~5 @1 p& V5 B Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。" I% u3 }8 x( N7 e
, H7 d% J7 T- T" u
3)Uses;9 F5 \8 M- |6 ]: E4 r$ X& E6 A
% A7 h% }5 n) {# z# x
指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
. \* F) E7 z/ w& d( i! a7 W
$ l7 K+ E% F/ M4 v6 V( a4)OrderPreference;
( B9 t: A: C, t2 q( r; G8 b" h# W9 k. y' r" ]2 A( W
指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。
8 n& S; Y, V% u' U x( r
1 n6 F* n# E3 _ }3 H5)Messages。& P5 O1 w- O# a6 h. O( L& ~
$ O- L! b& H, E& C1 }( G* q2.1.2 创建一个StartupParameters.plist文件6 }6 e( x# n4 W9 D( I; s! d
<?xml version="1.0" encoding="UTF-8"?>, M& w% I2 F$ [" {
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
# `" g) v2 X# A6 F "http://www.apple.com/DTDs/PropertyList-1.0.dtd">* t8 q7 l: i% Z
<plist version="1.0">1 x* z; n) D4 ~5 X
<dict>
0 k) [' _* T4 ? <key>Description</key>$ k" b1 V$ l$ T6 k% s; n
<string>Iceberg Control Tower Initilaization</string>
; d/ c. M6 @- D* U s0 p7 M9 u5 p <key>Provides</key>
, }* W1 _+ Q1 b) k A2 z4 t <array># x9 l2 L0 S: j! v
<string>Iceberg Control Tower</string>
' y# E( v0 h* Z( a </array>1 \: o/ H0 p! _* Q
<key>Uses</key>
; l7 K; O5 h v8 q) K6 g <array>. r* t! O# k. ?7 T1 m6 N
<string>Disks</string>3 [$ S u* J$ p7 S3 e1 l
</array>
3 Y7 p) U4 W2 ^2 w# a% G" \ <key>OrderPreference</key>
" r5 I/ i; b2 u$ f( z9 j+ q <string>None</string>
& e. q" ]% t& R4 {+ @" D</dict>
8 `, d7 y: G2 Z- F</plist>
7 ^, z! |) t% `$ |7 q4 l" N' H9 X- K
! U3 v9 f T1 @1 I* `; e7 A x+ a7 i! x8 B
2.2 The Executable File
, w3 ~5 D! C; c2 r) D2 e注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。
: I' L3 T1 W% c& b) ~
7 Q( O+ K3 b0 t5 @ 2)操作可执行文件需要获得root权限。# ?7 E- A- y4 |9 d+ ^
! N' d. H, x* J. D+ h8 |5 z
3)可执行文件是一个shell脚本。7 g0 }7 L4 D. ?+ a4 g, c z) y4 @* M
( _9 T, f0 g$ N3 v8 s打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:
; h* d6 u, `. P. a; }% F: h
7 M2 r! w4 [/ ?8 G j
5 h5 ^$ K* y, C, i3 A. b0 X* Y. c+ ]1 S' {! K G
一般的可执行文件包含这样几个方面的内容:
( J# t; G/ H' o3 }6 L6 c6 O4 H/ h+ E
3 u3 z' d2 N* M1)./etc/rc.common# ?9 L: V/ }! E( d4 f) e3 T! l% S" k
2 C$ p: \9 O, c5 M# F- jApple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。
! ?" L( I+ Y( Y! _" @6 X/ j9 l9 W( V, v0 S% P
2)StartService(), StopService(), RestartService()
7 p( T1 }3 H. `7 I% a3 u( L# m0 W- k$ R$ W0 p1 }4 u. g
当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。6 ^, C# l6 e( U" D) y. Y: g5 Y
8 A" W" R- ?8 {0 Q& T
参数含义:
$ m/ L$ F* V( j2 \" `4 e+ D0 }! Q3 w: ?. j
start:开机过程中开启服务;0 M9 u1 i) D% R3 H* Q# ?6 B( y
4 J4 `7 O/ o* `5 n! \# N! w
stop:关机过程中停止服务;
' I: j p1 F9 U* A" u1 y p; j# I/ u$ B9 U5 O
restart:在特定条件下重启服务。5 r; d& F+ y1 e& t
3 P3 l! q4 k! b0 U
3)RunService “$1”
% x: L+ O! Q4 Z% n2 K
) m8 H# ^* S& Y X" }( K. C执行传递给该脚本的第一个参数指定的服务。9 w1 e; F. I, M/ P
% w/ l7 |% J) ?1 K8 D
“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。- Q/ ~; I+ p1 e
3 a" I) N- t+ m' h6 R* n% }& R
3. Launchd Daemon/ S6 P* c& \6 E7 a. q' y
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。) ^! g" P8 W1 L Q) z7 }8 {
9 i, L/ \* d4 u* o+ \采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。
! R# O& n8 C/ ?3 b* c
- E* h8 H p) b- O$ v( ~3.1 plist文件格式及每个字段的含义:2 t4 R7 ~7 p {* ?9 f2 `
3 y+ k! f% S/ I K6 i `" O: U* T3 N& A( l$ a- }
1)Label【required】) |- l" A( u1 ? [! X0 j
, `- a: o1 L- A$ A& r
该项服务的名称。/ k; C! q( q$ s" Q- w- c
& U1 ]; W& B, d+ S5 n
2)OnDemand【optional】
# o2 Y u# q0 f. l# J. t5 m# |$ I+ T: T1 v' }" A% j% L/ o5 X
10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。
3 ]0 Y- i! g" k+ G/ y j" k2 T4 x# b8 l8 c/ x. a
3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】6 \* R# p. g$ U& B' C+ M
( e0 Z* k, A( K3 s6 U* w
指定可执行文件的路径。
. W5 f6 J' Y4 x7 }- |9 C$ H# p8 \9 \8 ~; q* P( R4 r# I
4)RunAtLoad【optional】
; s0 W* z- _+ g' [; u. c) A1 d3 v3 V- ?7 I" H; E5 J
标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。; T" ?6 d4 `* h8 G9 \7 F( |' n/ L
' s1 Q. s* a2 [" l. s' Q$ x7 W: V5)WorkingDirectory【optional】2 m ~9 l! M2 A& p( C! e L
% Q: k2 O Z* D a. e5 o8 Z该key在开启可执行文件之前,指定当前工作目录的路径。
7 j- p p* e8 e; v' h0 F2 B$ l( M) B" D: D% ^$ p1 q
6)KeepAlive【optional】% q6 ~5 A0 D1 j2 j! x. T+ z
- f( E+ P* T, y3 p* O2 G5 c
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。9 {2 t, t# E3 I7 [5 [! J+ }9 |
8 N; r8 r8 u0 q9 K( Q% i
3.2 创建一个plist文件:
, e" O1 h# o% q, h5 F$ ~. V<?xml version="1.0" encoding="UTF-8"?>
2 l" [4 X8 u+ v! h* q' E) v* |0 P<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
. Z, c+ f9 s+ T! _ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
6 R- v4 [7 [5 X* c/ u<plist version="1.0">
) S c; y1 I6 i! y<dict>
- `$ ?" b0 ^+ \/ E; [2 ^* m$ l' Z <key>Label</key>2 a2 x' ^# U: G7 Y
<string>com.yourcompany.HSPA_USB_MODEM</string>! h5 X% Q* x% T+ Y" Z
<key>OnDemand</key>
K |- P" {- j4 F& o% V <false/>
% t, }5 [' ~7 Y* T4 d3 X: q <key>Program</key>
, h6 p8 j4 b, z6 k4 x) D" L' O% A4 M <string>/Application/HSPA USB MODEM.app/Running</string>9 X1 }; M& w8 I7 J
<key>RunAtLoad</key>( w$ Z# _3 U8 j# g) d# I- G2 O
<true/>
- h" S5 Y. y6 z. M+ c% j <key>WorkingDirectory</key>
3 [- B0 Y( o& Z D0 T# V. Z <string>/Application/HSPA USB MODEM.app</string>
$ |3 e3 N$ L C/ U6 h</dict>
2 J4 N) @# S, f ?1 F3 y</plist>" i; ^ g6 Z2 X2 ]5 K0 n. h) ~
4.三种方式的区别
1 h; ?1 S4 E9 y- ]/ V, i初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。( _, n0 I' b1 [5 C5 H0 T2 J
4 R% Y+ K, `& k: \4 a# f% e3 N
总的来说,LoginItems 和StartupItems的区别较明显。
/ ^# y) A+ f% u. d. ^& j: D# }+ Y0 W; p% v
1 U+ K# A* c2 R" b* w! |; x对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。6 l5 z: N9 V' j: L6 p! O& u
|
|