- 在线时间
- 63 小时
- 最后登录
- 2019-5-3
- 注册时间
- 2004-5-10
- 听众数
- 443
- 收听数
- 0
- 能力
- -250 分
- 体力
- 10122 点
- 威望
- -12 点
- 阅读权限
- 150
- 积分
- -516
- 相册
- 6
- 日志
- 10
- 记录
- 10
- 帖子
- 2003
- 主题
- 1253
- 精华
- 43
- 分享
- 8
- 好友
- 1292

复兴中华数学头子
TA的每日心情 | 开心 2011-9-26 17:31 |
|---|
签到天数: 3 天 [LV.2]偶尔看看I
- 自我介绍
- 数学中国网站(www.madio.cn)是目前中国最大的数学建模交流社区
群组: 越狱吧 群组: 湖南工业大学数学建模同盟会 群组: 四川农业大学数学建模协会 群组: 重庆交通大学数学建模协会 群组: 中国矿业大学数学建模协会 |
2#
发表于 2004-9-27 14:27
|只看该作者
|
|邮箱已经成功绑定
如何实现自动登录Linux (Runlevel 5) 8 K6 B+ T5 s, }2 `# L% ?8 Z$ A" {
3 l: T1 i+ S4 }& {' J机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。 " \/ m R+ @# K5 _! c
一、linux启动的最后阶段的工作 * |' q: ^* C& Q% c) U5 x$ L
6 F- Q' l. E' f2 L; alinux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有:
, [2 B" Q/ o# \! z1 f1 l4 |! n, P. S2 M2 T" E
运行xdm启动X window; * b2 \9 m9 G4 R& {) ~2 T
运行gdm,进入gnome桌面环境; " e8 J/ c6 o6 D. X* I& Q/ O9 K
运行kdm进入kde桌面环境; ( s% y+ s, b9 _, y
自动登录进入linux; # W. U+ F4 w* q* u- Y4 F- w
prefdm脚本框架大致如下:
7 u4 K4 c K& L) a/ ]5 d9 V5 ?2 G6 z9 f6 C/ S
#!/bin/sh
6 B E! B( R6 k9 sPATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
' J$ s( t; \$ f3 d" b$ `, Y) n! m$ A. /etc/profile.d/lang.sh 6 ?: y, Q% {0 L$ ]7 ?7 `
# 第一步:查看是否为自动登录 # p- u! J$ c8 w' {
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then % ~/ U0 g3 u# s4 B( ~
if /usr/sbin/autologin; then & _6 V- n4 N3 b/ [1 P
exit 0 ( e7 x' J) w. G
fi
, a( U8 R* b4 G. l* W6 Rfi
2 o, v! `* e$ I( G5 R) `) w0 Z/ `! W: x# ^
# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式 9 M, S2 Q+ T/ w: ]) h
...... / U% Q0 E, d# y
# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。
8 @4 ]" e* R3 k+ w% [......
[5 Q* K: }( n0 R5 A# U
6 ^7 C: y- ^7 P( Z
" ~! v$ [/ q: l; j$ p- |
+ b6 l* e5 b& H# v: U2 Z" v* z% v& _1 D3 g) \* s6 E7 h% H& d5 K
二、自动登录的实现(autologin的实现)
7 s/ L7 z( a/ X* @3 K3 [+ p* K! Y- e" @
在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。 9 U' t9 L; z: e1 |+ A; n/ R/ z C
/ }2 F0 y$ k5 j4 U& g$ k% O自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。 + u4 D& Z |9 X5 o" j- s, A% A
; i$ N% }/ R S" j) _
Xinit用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。
% B6 e% J" W2 Y" [; x9 }' J( k# F+ F实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。
! M+ e- l! J8 u6 b. `startx脚本的最基本框架是:
6 H Y: h' n0 O0 f- M: e7 _, N) e) a* E* v
a、 寻找.xinitrc,如果没有则使用xinitrc;
+ t2 L: ^& S Z# o0 d# rb、 寻找.xserverrc,如果没有则使用xserverrc; $ L- }8 z9 r: y
c、 根据找到的脚本确定xinit的参数;
. @3 \' [) Z- D2 w6 y! o1 X/ w4 _( e' m# O' v) `
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录: & \. o/ I8 s* Y' u
) \9 Y1 W1 Z5 q8 }( {" A
1 L3 l) s. d( d1 z+ \/ [9 i2 m#!/bin/sh 2 V9 M% s, E% w5 |- j
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
3 b6 p" N) V$ k i! }! ^' }( w. /etc/profile.d/lang.sh
, b; v- v- f2 B( r" G5 w& Q3 A# 第一步:查看是否为自动登录
3 _8 q+ r* S. I4 C, u: ~#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then : \* x6 T3 j( @9 T( c/ }( l
#注释掉上边的条件测试,直接运行startx + w3 H1 ` P6 s) b5 ^$ Q
if /usr/X11R6/bin/startx; then
" `. u5 Z0 Z' Uexit 0
A. I, A; s; _% k* {fi / ?1 x o+ N' E( f/ [+ o! C4 M; m
#fi
. [* b t4 ?0 M; X3 a6 m4 ]+ Q5 Z6 [' c' T+ L% X
# l, N1 }' `3 v" x* D5 J( _+ x$ W$ `/ t h% P
5 X1 C* J1 t; R7 V. t1 g$ ?当然,应确保/etc/inittab中的启动级别为5。 8 f1 b8 j% r0 N% U2 v
0 |3 E+ c9 [% \重新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。 ) a4 a. C; F) F! N- U# o( y6 S
1 H2 J2 g+ h6 a6 X( ^) k* Z三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)。
* _, Z" Y; O1 L* O. O0 N1 U6 K8 g4 L
( d4 s: R* g+ T0 @5 p观察原来/etc/X11/prefdm脚本的自动登录部分:
! T" \; B+ A4 Z9 L1 j2 E& A& Z% B
- Z$ s5 R, l8 P) _& Y' I6 D2 {( R* Y# y" R6 }0 I- j m7 H- ~; {
...... / D$ e; m+ H5 R9 l% x: X7 Z$ ^
# 第一步:查看是否为自动登录 4 R% i+ ]3 [0 y& s# Z
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then $ |0 j/ U9 `+ x! h5 Q
if /usr/sbin/autologin; then
" O, z: f' p1 m$ Gexit 0
0 h4 Z3 _. g+ B- c5 `4 k% @fi 8 [1 s0 @- G, \) X
fi 4 b. x5 y7 w+ ]% r
......
% o4 e/ d2 z. t" G7 L7 i8 v' I& T1 x* ~: H8 r; a
g4 [' Z) W7 L/ k. F0 Q+ |# H- d& s0 s
, B9 h3 _* w" y2 y0 J不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。
7 K2 t; j, \0 w j5 s" |
& J! j+ r" a( ~: M1、/etc/sysconfig/autologin配置文件的实现:
& o4 y2 K; o- F* E- g- L
- g/ n* b1 w8 G& F* D, V, O4 G! B; d/ S( R, o. I# S2 X6 }; q9 ~
#config for autologin % c8 t2 `. F* [ |* @
USER=root & Q0 E& v) |) ]; N6 ^6 D1 j
EXEC=/usr/X11R6/bin/startx
! V8 E, r6 Z* h' D说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。
% \8 [& Y/ ?; c
/ M" J% r$ m* Y4 {0 ~
- H9 {/ ]- g2 w8 g4 m* V4 F: _. c
( x/ U" s" c( F. v$ a- W9 O: H
$ i- \ H8 S/ m+ o5 z2、/usr/sbin/autologin可执行文件的实现: # D$ F. m/ {: m$ o+ X: Z' K6 N8 K0 @& N
, v; I. E. U+ b" H1 Y) o+ l! ]' |) \0 W4 m* m
/********************* % s1 L1 |8 `; T7 H: V
**** autologin.c **** & A, O( P6 p7 i) X0 c* J
*********************/ 0 c1 i4 {; \8 l
#include <stdio.h> " K5 M# W; I: ^% l: _( d
#include <unistd.h>
+ B/ x6 }8 w E: e#include <string.h> 3 g' S W: Z. s7 X) m# H
#include <errno.h> - t+ y# V6 ~: ^9 y9 `6 }" U* C
#include <sys/types.h> , d$ a& F& d& y3 K+ x1 _# H* G
#include <sys/stat.h> 1 L" Y1 U# v* T
#include <pwd.h>
" T! z8 U/ @# j' [) a: H* a0 M7 I8 l! l* G. f
int main(int argc, char **argv)
8 W; j% M9 ^; O4 b" w{
3 e1 K. C8 K% Z; ~2 s2 wstruct stat st; 9 }3 E; d; w4 z _( O/ z# E
FILE *f;
9 `) V% ^4 s8 S5 z% H; Pchar *cfg; . ?) P( g; Y+ U, t" g: m
struct passwd *pw; 2 M8 w" L" C2 i o) y+ i- P4 ?; M
uid_t uid;
/ l+ |2 n0 Z5 i( R* i- P3 u6 W3 Ygid_t gid;
* g @' Y# P: R( _char *dir, *shell; $ N, H7 k( S" l! x
char *user=NULL;
3 x- b; ?! \, U2 M1 Echar *cmd=NULL;
6 S" F/ |) W6 `) J: K1 z6 D+ C+ P1 n0 @' }6 N" Z
user="root";
7 m3 b% l H0 y6 w/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上, " ~7 t% N& ^5 y$ j* O& z5 T
登陆用户名应该从/etc/sysconfig/autologin中得到,
8 P5 @ ?+ _3 }" Q1 x程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/ ! |: b- P: u9 n' x' a" H& [4 Q
cmd="/usr/X11R6/bin/startx"; # M; {" Y% v- `5 y1 R/ m6 x2 C
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/
: y6 v+ I! }* s3 J2 X8 n R+ Z O7 x o; E* H) I
pw = getpwnam(user); + E! Z1 X& v7 N& ~( B3 z
//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。
/ t2 w1 O* n$ J1 i; ]: L( `if(pw) { : C' j, i0 N; T9 }- S/ R
uid=pw->pw_uid;
. l' ~! D( G4 d) |gid=pw->pw_gid; dir=strdup(pw->pw_dir); + G" i' q. X8 ]* ?9 B" ^
shell=strdup(pw->pw_shell);
/ v0 }+ v* I3 \4 w! R}
! [2 }4 m9 @3 r" E9 M1 p$ v//获得用户相关信息
; i5 J+ b2 j1 J3 _2 v9 N* p else {
, @9 f& G# ?2 }- p- @4 g; {+ Sprintf("ERROR: No such user %s!\n", user);
0 x! X# h2 {1 h" ireturn 1;
# H: ?4 v2 e+ A}
3 o7 \( U3 U, f: H q4 `) ?2 K, S* C4 x s2 C) J1 s
chown("/dev/console", uid, gid); 8 B; n! \, k$ e
chown("/dev/tty", uid, gid);
% O' I' n. m7 W8 B8 I//为控制台和终端设置用户ID及组ID
~& u' ^( E1 y& w9 E* R
X2 W8 Y% B- i" H4 P! e6 b//下面是设置用户相关ID
9 Z; T% M. }% R/ k4 b1 R/ O, s: ssetregid(gid, gid); 7 M4 L+ w0 X. I9 i0 I
setegid(gid);
& Y, W9 ~( w- Tsetgid(gid);
0 {$ M3 @( ^! Y- v% W3 m& W$ S7 H+ xsetreuid(uid, uid); " `4 i2 i4 F4 n
seteuid(uid); " d: q+ i8 C, c$ s; Y0 D5 o- `
setuid(uid); 5 [! h! q" B: s3 {6 [0 W
/ t, U+ [- s* O. Q7 K! R
setenv("HOME", dir, 1); ! v: [* X. C* { { ]
setenv("SHELL", shell, 1); J6 I, k1 s" e- \
setenv("USER", user, 1); ! J8 K2 d& y6 m# v3 p6 Z: @
setenv("LOGNAME", user, 1);
/ _1 j/ ?* Q! N* G//设置用户相关环境变量
) C# }, ?: k n. d4 `! ]! m! e9 B" F0 q
chdir(dir); 4 d# s z3 e1 V& O, R) F5 @
//切换到用户根目录
' W6 f8 m! p2 i, d4 vuser=NULL; 6 X4 ]0 g, L. q& m3 _
- f: H$ G* C3 i' ~execvp(cmd, argv);
. f' v P. ^; {: {0 C' a- @/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */
* N3 c1 l& I( }8 Yprintf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
9 n8 M5 {$ ?" Ureturn 2; 1 L3 R5 u* m) e+ J- @
} # O( w2 c: q7 b( |) o* T4 S1 R5 z
) w3 ^, n) J( ~
& N% U# |$ M" r6 l3 D& N' a/ H3 _* R2 u- h# O4 ]1 t
6 ~* H! D* i2 I8 t运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。
& I7 r& p$ Q6 q6 H/ _, U
# @! ~0 e u: p. H& P如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下: 6 a. N# S6 ?4 ]4 y2 o
) ^# M. t6 e& P( ?' ^
$ P$ K: w% X! Y" _6 k% Z. H& Z3 F...... 4 t- F" c2 }( |$ S+ D
# 第一步:查看是否为自动登录
) C) G& R. o: g& eif /usr/sbin/autologin; then
0 E, h* ?4 V p Q' Aexit 0 % ?4 D/ n& d" H3 x S
fi 5 v/ d' O3 v3 l' i* u1 T: G: R- m
//第二步 ...... ) H, _6 G$ `+ I5 o
......
1 Y. u" q# c- _4 m* ^/ D9 d- ~. h9 k2 Q$ ~2 Z5 M( L
$ g$ v7 ?) M; i+ d
: L; B6 G6 u3 L7 h% w
! w* G/ A0 d# M/ C( r( Z4 k即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。
: g. c3 Z3 Z2 U& a3 M4 n
% Y* V! B* e9 O" O/ v四、选择进入kde或者gnome,并自动启动X window应用程序
' c. V5 I2 }. B [& V
" ?' m- ]8 W. [0 x如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。 ! y3 d% l# [& X5 ]
一般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startup programs属性页中即可。 ; T C( l3 ]6 A$ t# V7 f5 o
: R" U* @4 a) X( c( n$ I* I* _0 I1 ~3 y [& O+ e: J# Y
http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip20/index.shtml |
|