|
|
在Mac OS X中,有三种方式来实现启动项的配置:1)Login Items;2)StartupItems;3)launchd daemon。
# o! Y w" K, R, b; P$ E9 `* s
2 K, @% Z8 t9 ]- c" d' x$ F1.Login Items9 X* o1 U/ ^# r$ Q L+ \
打开System Preferences,选择System -> Accounts,选择Login Items选项卡,将/Applications目录下的.app直接拖进右边的列表中。重启电脑之后就会发现列表中的程序在开机之后就自动启动了。; M! U% S+ m. L
1 k' n. m& t4 a% X5 x: [- J
1 A+ ]% `$ J% L- u7 M) O) o
* X- M1 ~. T3 s% a) y7 S# P4 P: i; W" v2.StartupItems
1 ]0 |7 a- O: E) I8 R/ T1 E5 U) iStartupItems,顾名思义,就是在系统启动过程中运行的程序,它们可以是运行完就立即终止的程序(比如,开机清空废纸篓),也可以是一直持续在系统运行周期的后台进程。
: l u! z% C. ~& Y; Q5 k" R! j- N3 d1 u+ j5 j7 }' a! w5 F
StartupItems一般存放在以下两个路径下:- S- t$ L6 w- f' P- t
4 C4 q+ z, ] S8 [' C/ o) i- ~' ~! ^
1)/System/Library/StartupItems1 U; p: ^: M: n# `) T$ t
6 l9 n% \& p& |6 G1 C3 a( E$ j2)/Library/StartupItems) M8 K, R) H7 b |8 }" x
7 W1 _- N; _ x
大部分与系统相关的StartupItems都放在/System/Library/StartupItems这个路径下,它们会先于/Library/StartupItems路径下的执行,因为前者路径下的StartupItems提供了系统级的基础服务,比如crash reporting,core graphics services,system accounting等,而后者路径在默认情况下是不存在的,需要自己手动创建。 @3 L5 u4 ]* w% @* B
0 ?0 g) S1 [ C
这里我们以/Library/StartupItems目录下的IcebergControlTower为例。0 e4 C5 J: m6 [! w, o
5 Z0 {: B& \( e1 p
6 z5 M2 L f. Y$ x0 {7 H) U
; ?9 B; | S8 _& B4 h$ _简单来说,在Mac OS X上,一个StartupItems包含以下两个方面的内容:; x4 K3 O% q& Q8 `5 f
3 S) l/ p* G+ B N
1)可执行程序;! D% l, o2 b- G3 M7 N
8 b/ l% {3 K* T. ]2 J, \: m D0 G
2)包含依赖进程关系的plist文件(StartupParameters.plist)。3 p4 ?' H/ @. F/ C7 l8 r8 I
8 {% @, x( B$ F( n2 L/ F: }4 n, o2.1 The Property List
2 K) y$ m" U! N# S: H2.1.1 Plist的key值与含义4 R$ N) ^" X4 P3 c# `0 Q$ R
StartupParameters.plist 是一个属性列表,包含了运行可执行程序的必要条件。
. e( w. h& K" l" I, z! x, M
% q4 \9 l: x0 a+ j
6 L' S9 q2 [' k$ n/ m4 u. b: h4 y5 N7 ]
0 a/ r6 I. w3 a8 Z3 v) p$ z/ _( j该plist需要获得root权限,包含了几个方面的内容:7 b# ]- C' [: N% W6 S; A a+ r
/ m2 M! s, ?5 w, U7 e( a1)Description;+ N/ [! }$ e' y4 D6 g: t6 w
% t7 A, d" t2 R
对该服务的一个简单的描述,仅仅是描述,并不是说明实际的进程名称。" j4 ^5 O0 ]' m4 r
. @$ [) ?% z8 y# T2)Provides;+ @" c% }- v# @0 Z( e- G
+ V3 a$ a/ f/ z" l 指定StartupItems提供的服务。如图plist文件Provides中说明,StartupItems开启的后台进程名为:Iceberg Control Tower。
, O! m0 k5 f1 ~2 T3 W% z
5 p7 M. B9 p( Q; v/ _2 a' Y x Provides可以指定多个服务,反映在图中就是Item0,Item1…等。这里只有Item0。
9 ?% j5 Q" M. |
) d0 W- ?/ Q: E5 W. p3)Uses;( L9 D P6 Q: x* N0 [% y f
% Q5 ?2 ^6 w) x* E) \& y 指定了在StartupItems加载之前需要开启的服务。Mac OS X系统先尝试着加载Uses中指定的服务,然后再加载StartupItems。也就是说,即使Uses中指定的服务没有加载成功,系统仍然会加载StartupItems。
9 F$ t1 Y8 m5 ]7 F+ x2 r% f- g. k0 l7 G
4)OrderPreference;
6 k& P4 C. |: f5 K1 W
: s! d/ C, L& [" F 指定执行StartupItems的时间顺序。这个顺序的重要程度排在Uses之后,是指定执行完Uses之后的顺序。可能的取值包括:First, Early, None(default), Late, Last。
, ?5 r2 Q: R8 M$ B/ q) E3 T( W/ \! q7 G) K
5)Messages。
( s5 o6 ^: U( b, o: S0 _5 e
# X5 C# n9 ]# J, Q2 q2.1.2 创建一个StartupParameters.plist文件. ]0 ~' k* m8 Z8 h4 a! V
<?xml version="1.0" encoding="UTF-8"?>
* _7 G8 F6 {/ _ U1 P<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 4 C4 B+ k" q* {9 g$ `
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
" d# _; R: ~' J$ R9 ^<plist version="1.0">& P, _. y2 }. V4 W- _
<dict>9 q8 e2 P" s5 ]% ^; @
<key>Description</key>
# A' q. k: ^/ t' M5 b: O5 n: f <string>Iceberg Control Tower Initilaization</string>
2 N- i( n( W, d( t5 U3 w# E ~ <key>Provides</key>& ^) P6 s0 J m/ T3 z- r
<array># K* N' c" D" M q" ^" s
<string>Iceberg Control Tower</string>
) p2 r/ t4 K _; @$ ~ </array>* G7 ?4 J/ F% }4 u: z" E" ]# u
<key>Uses</key> [2 H" L, m: U$ Z
<array>
- Y4 n9 |9 _* G- A4 G6 J <string>Disks</string>* E- j. A+ l/ O; W) v t! E
</array>) k. S$ J2 W3 g- W; j! l% X3 a Q
<key>OrderPreference</key>6 J4 K3 @& v- w( Y" T; c8 l
<string>None</string>9 C4 {' R9 K P2 a
</dict>3 T& X& B. I2 D4 L% z
</plist>
( W& @4 {4 \) P- m
; ?/ \# F: N9 G( `' _9 Z* m
' f; |* F# L- E1 e* y
- Q" C0 \( Y: f8 k# J% z2.2 The Executable File
8 C& _- o: b+ O" I6 D注意:1)可执行文件的名称和它所在的文件夹的文件名是一样的,这是系统默认的规则。
W* O* @, k" `; D' r. v
; K- c$ ?- x: D% [4 U7 z 2)操作可执行文件需要获得root权限。
4 i9 e9 |/ y7 Z/ G. m' x; m, b/ s
2 M4 u! p3 W8 V# C 3)可执行文件是一个shell脚本。
0 \# ~) ?1 M' G$ w: W& f$ K/ U1 Y+ J: S0 c: T6 B2 ^) j* N' d' p
打开IcebergControlTower文件目录下同名的可执行文件,可以看到脚本的具体内容:
% V) g! j# A2 T6 X4 X4 }
) q5 f- h, u2 G# _! F$ [3 {! V+ f9 M. Q0 z+ t0 P) I
, G" Y1 O4 g7 S一般的可执行文件包含这样几个方面的内容:
& L! \4 y+ O6 g6 Q5 S
& [4 j- T! R- G8 S& L, e6 N1)./etc/rc.common! l- s, W2 a' j9 {9 l5 V" @
S ]* r n; ?8 K) C: h" d
Apple提供的一个脚本库,该脚本库里包含了为可执行文件引进参数的接口。在这里load这个库主要是调用RunService。1 {% p: @, {$ i3 P# U% p* g) r
# w7 ?- B# G) \7 N7 x( k. ~2 m
2)StartService(), StopService(), RestartService()
8 J0 F4 q A9 n) x8 X2 L0 i9 I7 h& A) d$ ^. N7 P7 I- }4 M
当可执行文件接收到的参数为start,stop或者restart时,执行相对应的函数。
) c" i& o, H4 r7 {' Q/ j$ b! L9 U0 I; n, x9 x& x" G
参数含义:
7 U% i- f0 C8 V% W4 v5 Y+ c4 f) N* }5 F, ^9 |& R
start:开机过程中开启服务;
3 \1 l7 H0 S; s- y2 I2 W8 j9 o/ R( o3 f# v) k8 [
stop:关机过程中停止服务;
# X4 Z% Z# ] P) t6 Z* w
, x; f/ I- h1 s: ^% I- R- [restart:在特定条件下重启服务。
B9 e2 E( e! W- k$ S6 D! B6 L8 A6 g9 o
3)RunService “$1”
% X. ]3 {) @* ~' W& U- s+ ]9 A+ p! c8 ]; X- p$ O
执行传递给该脚本的第一个参数指定的服务。
& b* e' {9 x/ r8 [4 ]& {- m% o$ P7 y: E: S6 m0 c
“$1” 表示传给该脚本的第一个参数。例如,传入的参数为start,则执行StartService()。9 R: U: r3 o6 f; o4 f' @
' l0 \: J* l- Q; J3. Launchd Daemon6 ], j# P8 Y6 |( P: V
launchd是Mac OS下用于初始化系统环境的关键进程,它是内核装载成功之后在OS环境下启动的第一个进程。
+ U) `- g8 \2 r: ?" }
: A1 i5 l6 u# ^采用这种方式来配置自启动项很简单,只需要一个plist文件,通常(同时也是系统推荐)是将plist放在~/Library/LaunchAgents路径下。
3 z( a: e' f1 v) p, f1 t4 ^
6 s! Z# p, T% q4 |4 K' }$ R3.1 plist文件格式及每个字段的含义:0 _7 C( J3 j3 }! o+ L2 f5 B
" K3 t8 K% X$ P$ A- g
- b- `) s9 h* d0 W6 ]4 s* P7 r1)Label【required】* n2 [, L0 B8 E; N% Y
7 q) m" k% M7 F1 |, `
该项服务的名称。& b; Q" k) f; X6 }1 J. l- L
; r8 M% K. Q5 i- Y8 e8 ^2)OnDemand【optional】
9 p- r8 d1 v3 k+ [- x' f* T9 b3 z! N7 h+ H! J) F8 H8 F
10.4提供的一个key值,功能与KeepAlive的基本功能相似,在10.5及之后的系统中被KeepAlive替代。KeepAlive扩展了更多的功能,除了使用单一的boolean作为key值之外,还能使用字典结合多个key值。$ L" J1 G9 S G/ z/ q
0 U$ R+ x5 \' x8 }. Q8 x' E) M; }3)Program【ProgramArgument是required的,在没有ProgramArgument的情况下,必须要包含Program这个key】
& G V0 f( z* J+ `# A7 h/ S/ T2 y2 A/ q, D1 |! W% H& D
指定可执行文件的路径。1 k" j) S% Z J8 p
3 l- k* Q' O& `7 N
4)RunAtLoad【optional】
! N' m& b$ M/ {# s
0 t; P' q$ X! y0 ?; o) V- B标识launchd在加载完该项服务之后立即启动路径指定的可执行文件。默认值为false。1 f% g& L9 j4 L* M3 D1 g* E
0 ?8 y# K4 \8 j/ S
5)WorkingDirectory【optional】5 u! }' P1 v6 y# @
/ @' Z: O& X! n3 F$ \! U! \
该key在开启可执行文件之前,指定当前工作目录的路径。
; {6 g0 k& S) |# u
9 c0 G1 s+ J" Z" j3 l2 i* n) i M/ S7 L6)KeepAlive【optional】
: y1 {) t& U5 W- A: _. Z# h3 D1 y$ Z
这个key值是用来控制可执行文件是持续运行呢,还是满足具体条件之后再启动。默认值为false,也就是说满足具体条件之后才启动。当设置值为ture时,表明无条件的开启可执行文件,并使之保持在整个系统运行周期内。
7 c$ t4 O- u3 u* n( U! G) {4 [- q1 f/ V6 t7 G' ~% [! V, q$ [( F3 Y
3.2 创建一个plist文件:' X9 ^- ^. Z) ~ q0 j( M
<?xml version="1.0" encoding="UTF-8"?>3 h8 h* [0 Q# }7 n* ?
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
. b) H; d9 T: x; e! ^4 B "http://www.apple.com/DTDs/PropertyList-1.0.dtd">) Y7 O1 C/ g _* w
<plist version="1.0">
6 e4 `+ Q0 [8 X; b<dict>
; r' V4 ?6 N0 A. } <key>Label</key>
, T: |9 p% Y4 ~6 R* Z <string>com.yourcompany.HSPA_USB_MODEM</string>
6 z% c1 l4 s& m' r) p <key>OnDemand</key>! `9 q& k/ R- S2 Z" U9 g! X V+ G
<false/>! K. k6 C2 l7 v. B: u9 V7 U
<key>Program</key># w( @7 x" t! {9 c- U- f- m1 V( q
<string>/Application/HSPA USB MODEM.app/Running</string>
8 u. v" u0 X; A0 T <key>RunAtLoad</key>
, }4 V7 z6 N( P0 G- Y <true/>
( f0 L% m! r7 Y( d2 s" q V% i <key>WorkingDirectory</key>
- `4 P8 R* L2 h4 j <string>/Application/HSPA USB MODEM.app</string>
1 y- }$ a8 Z, `, Y K* p</dict>
+ H3 t( p7 Y1 \- T</plist>
( e/ U( I- ?5 S8 ?( F4 k6 J4.三种方式的区别% R8 b. q; H8 K3 Z0 m+ j5 ~3 O7 ~
初步了解了系统的启动过程之后,再来看这三种配置启动项的方式,就很容易理解这三种方式之间的差异了。
) I$ S7 [1 ^* P" B- n; D
" Y8 w$ k4 `9 M5 t$ P; z7 `: L总的来说,LoginItems 和StartupItems的区别较明显。" O3 A( j; |* S
d! }# a3 g# k5 U8 P& h; ?) J+ ~+ W, V/ B6 G" u6 A. b: M7 c
对于我们自定义的Launchd daemon,通常(同时也是系统推荐)是放在~/Library/LaunchAgents路径下。launchd进程需要在用户login之后才能加载。这种方式与LoginItems最大的区别在于,启动的进程不同。LoginItems是通过loginwindow去启动的,而Launchd daemon是通过com.apple.launchd.peruser启动。
5 @4 c/ B+ T! k% k |
|