|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。( i/ H$ i. `$ @3 U
$ T1 e+ \& h( O
1.Login Items
; i) c/ l; [& k! A" D打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。
: Z& b: Q6 L5 {% X( }4 z
1 V6 z z8 m+ o, Y4 p, t$ d# x4 K5 p
7 J( n9 a6 g, P
2.StartupItems
% }/ v" ]" Y3 e0 sStartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。' k0 T# {# g. P+ B* r
c. q6 g# N0 P7 T; k. H8 O
StartupItems一般存放在以下两个路径下:5 y! j8 K8 c# `" ~; z' v5 _' C
0 D Y$ Z! G8 y; P# Q1 ?1)/System/Library/StartupItems
2 C3 X; G }+ z6 Y
7 W0 ~4 C" |1 i6 A2)/Library/StartupItems
% l ~ g3 _; y! n1 J% T# c. }; f9 J) m
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。
, t) s/ x; V& k! R# Q& D4 P% X2 \3 f# Z1 p+ N
这里我们以/Library/StartupItems目录下的IcebergControlTower为例。
( v/ j, w" H6 ~- V& B- P1 M
) v* L/ x* V: e! v1 ~ M8 c4 @* v% R, z1 P" M7 r
8 w! v, b) O& V3 k6 e( Y! {5 |
简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:
6 d1 u, m- {* l2 L, D+ S! o: Q2 J) s( f3 u; D" R
1)可执行程序;! w0 b" X6 K {' l! A. N
( n& W" N1 _, q; ^2)包含依赖进程关系的plist文件(StartupParameters.plist)。
/ P6 F/ o+ r6 |/ R5 [
% }( i( ~% T/ ~8 P( X+ o' k9 _# |2.1 The Property List8 T/ ]+ x( q+ E$ G2 d6 l, x
2.1.1 Plist的key值与含义
% ]) f' G1 O5 `StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。3 {9 k3 Q3 P' j$ \# X7 l
" _& Z. r! U9 H$ \7 C1 }3 o
; _* ^+ j! h9 W4 f2 k$ B [
* Y( ]/ r, Q3 b, F3 k( T该plist需要获得root权限,包含了几个方面的内容:1 d$ {) e: c8 H
; e, o& O. J+ E0 ?1)Description;
+ C- `* L+ i" @6 ~5 t! h4 o9 L; o& h
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。
: T( Z( H" p! C0 |8 f2 X" L: R- V1 Y/ `4 ?
2)Provides;( O2 j# M7 Z6 M Y, e s
9 J% A. G) {3 }9 X( t/ ?- M2 n1 }
指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。. e+ }1 Q( v& S$ x" k8 S( ?* V
5 D5 E" k9 {- R) V8 J3 Q
Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。9 L! V! H5 M5 n, g9 G% W
8 \& O% W& w7 {7 z" i! l5 R% w" D
3)Uses;
& h1 L* Q9 ~! A# ?' G" ?9 T+ k& f1 ]5 T2 G2 S' y* F0 U
指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
: N* E* w! Q: L- s8 s' Y# P" N+ H0 {
4)OrderPreference;6 F v. j1 h; K' |
# }) ^9 @: n, f, _" U; n- e% g
指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。$ j7 l) ]+ Y+ b" [
' |: j" U% a0 y& s9 {5 M1 T3 M5)Messages。
4 q1 A8 s1 X1 u' @, e/ H$ q* s* Q7 @3 ]9 a/ w I
2.1.2 创建一个StartupParameters.plist文件" M* [$ S' | S$ f' i7 J' t8 `
<?xml version="1.0" encoding="UTF-8"?>
6 m- t+ e; s% J2 ?<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 1 N" ~/ D2 _6 Y1 B& A5 I
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
. K4 `" b2 k& \! d% @' H: b<plist version="1.0">7 b" K8 i0 g+ Z- k+ u0 R3 M- Q
<dict>
! d y; T) K9 S6 H. j <key>Description</key>
$ ^: r) N" @0 n0 {3 D: M <string>Iceberg Control Tower Initilaization</string># O7 G/ e7 p5 n4 Y
<key>Provides</key>
- ~1 {; J4 @* C% U% V <array>5 e$ Z! E% o1 {' W6 a
<string>Iceberg Control Tower</string>
9 Z- ^1 t2 D/ T |# A </array># u3 W$ p# D+ p x1 H6 O# M
<key>Uses</key>: Y9 C. v4 s4 A: _, a/ L
<array>
6 G( S" Y4 V3 Q/ [ ?/ ^ <string>Disks</string>
6 I8 T2 a; T4 j* R6 S' q </array>) w/ m! w' h, G9 K
<key>OrderPreference</key>
; A3 p5 }- ?- K$ d <string>None</string>
8 T. ^, Z6 f2 |$ m$ p% V) M5 }: g</dict>
" I8 B6 w+ ]! t/ k" _, \</plist>! J' N' _% ]' Y3 ?# g& t
8 G' `1 N/ d7 ?1 _" V6 p# A 2 t* n; n( V6 H1 f: h
' g+ S2 ]. u. `$ V
2.2 The Executable File) J8 O" J# {# l' |! Q
注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。
6 ]# U* z4 h* w. h$ U' s
) ?5 U& z* R3 b. j 2)操作可执行文件需要获得root权限。+ M! w5 [# W% g5 a, n$ M2 ~2 F
5 n$ K4 y# W! D+ V0 B/ v& s7 { 3)可执行文件是一个shell脚本。8 R* x! r. l' V K$ Q
3 ^$ b1 S4 y# {/ G1 o打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:% e& N! Z( m7 ^
2 S; ^" |) E9 M* V) E3 @+ W' z
" i8 x4 B9 U* U# {6 R2 H* `
" |% g4 G& i( q3 r0 E. ?一般的可执行文件包含这样几个方面的内容:& b! K% R' @+ {4 j
( b/ u, P; ~2 K! s4 i7 q
1)./etc/rc.common
' p0 ~$ i' A K4 n5 }+ D9 y2 J/ T! j; C7 l2 _
Apple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。
7 ?4 Y" L9 q+ C; r$ A& \0 |# ^6 i: l! F r/ e8 t* n2 u2 w# o
2)StartService(), StopService(), RestartService()3 [$ e) n; J- r
; M/ u) [0 r& Y
当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。
/ y/ g6 |+ K6 V7 D' K' k( k. Y. Z" X R' u) [8 L" c
参数含义:
4 H) r8 L9 `1 I- {, G9 `! A% R; p! j
start:开机过程中开启服务;6 T) Y; ?+ g ?* }
7 }+ j! v) [6 H; `
stop:关机过程中停止服务;
2 _9 x" `7 Y3 [1 Z2 A5 @* Y5 { r3 x6 E' y# z" H/ Y+ z+ {6 F+ M
restart:在特定条件下重启服务。5 L7 P5 ^4 V% y. S; W% ]" |6 L
* P$ W5 h1 `; Z; P) R3)RunService “$1”8 W; Q/ H5 _' q" K$ k( W+ v
( Z# s; `( m/ [ ~- @& Z1 _6 ^执行传递给该脚本的第一个参数指定的服务。
) g# I; ?, S2 H9 b/ B* s, Z$ @( e, R
/ _ g9 a' ~8 w. @ Q4 K$ ?“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。' z; _" q% t$ u2 o9 t6 }
. J) j4 }( p: ~, n: [3. Launchd Daemon3 z% n0 A& ^& p2 {! `
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。
* d* t& n9 `$ \; s
k- p: g2 i# ]6 u( u采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。
. d; T, ^; G" l- P# E& _! h
" ]% ]0 D$ G N$ b; d& p7 i* X3.1 plist文件格式及每个字段的含义:7 G4 H3 H1 L m, |+ `
( ]4 l" |. O7 K2 R+ T+ x# v) G' I- u2 p2 W0 T( O d
1)Label【required】- ~* m9 X! ~1 l
, L% v' I4 k/ P0 ~% u
该项服务的名称。
) c' K$ Q- S, j
: a, I& n9 {: q# Y f0 l2)OnDemand【optional】% B, W8 t5 W- C
2 K4 H; @2 m7 ~2 z10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。* l+ R% e% k& k! k' o
) o7 R8 M2 j/ Z3 H3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】' y* h* b) m0 ~) x+ Y
j1 }4 p4 |# z8 `. ]- b* d指定可执行文件的路径。# V. q: |0 [6 l! G9 F
' |6 J8 ?6 s/ a9 t/ r
4)RunAtLoad【optional】
- q( w5 s4 D7 ?7 y% a* [5 y7 h
% Y( m1 u! G8 F* L& i ]标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。
7 I3 _& J: m# m$ Q% J) `; S [/ J# `8 I% e
5)WorkingDirectory【optional】2 [# w1 A& M4 b0 F; [0 a; j, o* s
, L% a( k0 x3 `9 z/ D* N% @
该key在开启可执行文件之前,指定当前工作目录的路径。4 \$ |: J2 @2 q/ Y
* y2 s: z9 l6 K P
6)KeepAlive【optional】
& L: N, U" B* \% t% o' g) i6 H9 B/ m' `5 M0 v
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。
' M3 M# e! j5 V4 `; \+ O
3 M; C- h3 \" \/ @" q1 w3.2 创建一个plist文件:
+ x2 ^ O8 Z6 E3 N7 R y3 z<?xml version="1.0" encoding="UTF-8"?>
/ B) w) @( f0 E( A' R% ?' ], O8 @<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
+ C. `. j* Y$ s! u$ c, | "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
u$ h* A; O- k<plist version="1.0">, o3 T1 r" M& X# L1 g, J7 l& o
<dict>
1 s, d" p, ] A& M# ^5 a% U+ M <key>Label</key>& ~; ^+ G' x6 x& P1 p- d% d6 S0 X; g/ N
<string>com.yourcompany.HSPA_USB_MODEM</string>0 A4 z. ^" _6 }- w \+ a: D/ ?
<key>OnDemand</key>
! f7 L2 P& Q: j" h0 M5 U* B7 A1 l <false/>
3 J2 I! t, J5 b- u& W <key>Program</key>& w: B% B; Q1 V8 t& ?2 h& l
<string>/Application/HSPA USB MODEM.app/Running</string>4 `, T" ]" n9 ?' Z, m* K
<key>RunAtLoad</key>
* p! a4 l$ m% j6 C# G w <true/>
/ t( E$ g) c( S. y3 y( l+ y5 E <key>WorkingDirectory</key>
1 T$ B% S& ?/ v$ s( a <string>/Application/HSPA USB MODEM.app</string>
4 L e: f! l' j/ m0 n" X</dict>( `0 `; G- P2 j( D& ^4 [
</plist>. o/ l3 g( R& r
4.三种方式的区别
* e" j' ]; J! l( B- v: K初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。 `$ E1 M+ S" j: S
; v/ j$ i0 z7 l7 {1 ~) }总的来说,LoginItems 和StartupItems的区别较明显。
7 L9 Q. ?. B/ ]: L" y3 s
5 D& Z+ S0 y( Z5 Z! v" @- m6 o. a% R, u
对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。
; P* s |6 R* _5 a |
|