开机自动登录
Linux,并自动运行XWindow应用
程序,有其特殊的应用背景,如基于Linux平台的监控
系统,Linux启动后不需要身份验证,而直接运行监控程序等等。本文以
Redhat7.2为平台,结合Linux启动过程,介绍了如何避免身份验证自动登录,并直接进入XWindow自动运行应用程序。
* ~( g) k& z. D
一、Linux启动的最后阶段的工作
$ v4 |; w" b, V1 x Linux在启动过程的最后阶段(具体启动步骤略),init会根据/etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm-nodaemon运行/etc/X11/prefdm脚本,(Redhat7.2缺省时是这样的)。prefdm脚本的主要任务是完成XWindow的启动,可以有几种启动XWindow的方法,都包含在prefdm脚本中,几种主要方法有:
~4 s& {4 G7 [ W% `; Z t
运行xdm启动XWindow;
; ?4 v$ }! O/ Z/ y0 @8 d. a
运行gdm,进入gnome桌面
环境;
+ B3 M( W5 a$ {+ p 运行kdm进入kde桌面环境;
8 a( }7 Z( Y ~. h 自动登录进入Linux;
7 g5 Q; J6 {! h" E G[color=#FFFFFF']
% H; \: f- V [7 j% Z7 g2 r( E- X8 c
prefdm脚本框架大致如下:
- G2 ]( w' V; i' |3 l#!/bin/sh
) r+ z! D9 |& O& v: ]4 i* f3 J# FPATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
* u4 s* L, z! B& {# v./etc/profile.d/lang.sh
" V. B! `0 g# \6 F6 e) _( l
#第一步:查看是否为自动登录
9 b+ F, q3 U& @: A9 Y7 \if[-f/etc/sysconfig/autologin-a-x/usr/sbin/autologin];then
T$ T M7 y6 r+ @& c if/usr/sbin/autologin;then
. I& Z" a8 K0 a- \ exit0
; r2 ^5 U w: L# N% ^- D fi
7 g% `5 Q F4 n7 h
fi
' s" _2 ~# k& Z/ [& h/ ?
[color=#FFFFFF']
5 I& }% i* d2 V' a- J4 H
5 R6 d/ F$ X# O9 W
#第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式
% N( m A. q; [6 ?; U) {+ g ......
* A9 r% I( U3 v/ H/ t2 H#可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。
5 N0 A2 [9 V/ ?; k. G2 [ B
......
H3 ?) q& X- n' ^8 p
二、自动登录的实现(autologin的实现)
6 e5 a4 r. j' f! e7 F
# F" Q0 V* V- c8 K# [4 M 在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件
测试开关,事实上,可以在这里注释掉测试开关,直接执行启动XWindow的操作。
: v( f7 L0 ^6 B
自动登录实质上就是绕过身份验证,直接启动XWindow。XWindow的启动可以由xinit来完成。
) `% v, ^5 J2 L8 ^. I. O+ B
Xinit用来启动XWindow系统
服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行.xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行.xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X:0。实际上,用startx来启动X更为方便。对于运行单一会话的XWindow系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找.xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。startx脚本的最基本框架是:
4 T+ T5 e- s* a6 a; [
a、寻找.xinitrc,如果没有则使用xinitrc;
% a* t; m% ]+ l( p b、寻找.xserverrc,如果没有则使用xserverrc;
: A* V6 k: m, e) F! P' J
c、根据找到的脚本确定xinit的参数;
1 E9 B g; d( P P3 k7 [& U
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录:
. `2 e* w4 Z+ E[color=#FFFFFF']
! r9 x- i5 ^: R: g
* x; J; o, h+ H#!/bin/sh
. T5 h! X* Q& N* m7 Y
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
J t1 g- U7 Q c0 J./etc/profile.d/lang.sh
/ k4 I6 P9 V% K- R& v7 i+ a#第一步:查看是否为自动登录
* w$ }3 C/ `8 b#if[-f/etc/sysconfig/autologin-a-x/usr/sbin/autologin];then
. g8 N0 J& L" {: o) N#注释掉上边的条件测试,直接运行startx
- @2 y4 n, x# N$ q6 h: @ if/usr/X11R6/bin/startx;then
% a5 g( ]; i7 t L* P6 [ t5 Z exit0
5 p( l; E' W4 D( F1 g6 h0 t/ k fi
, m7 |) x2 B6 O5 Y g#fi
6 H4 F) W/ M' ~* {! U" E6 }) Q$ X" x[color=#FFFFFF']
( w* o. E' h8 q% q% B. o1 d0 z" G2 h) s- |6 E
当然,应确保/etc/inittab中的启动级别为5。
! X) i0 E) P r( ^( u: f# M
重新启动系统,会发现系统不验证用户身份,直接进入XWindow,此时的用户身份为root。但是,如果原来root有自己的桌面、默认
shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。
" e$ _- R3 u: L3 P2 |, F5 Q4 A 三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)
9 _6 Q+ \. V6 Y
! K2 [+ O7 f' ~7 I* f E& g8 N 观察原来/etc/X11/prefdm脚本的自动登录部分:
" p: y/ y [+ t9 k......
, x0 U9 ?) B% E# a/ `
#第一步:查看是否为自动登录
& k+ S F. V: J6 w" D: ]if[-f/etc/sysconfig/autologin-a-x/usr/sbin/autologin];then
$ w; W& \6 S5 ^6 d* {1 P$ z8 U* C
if/usr/sbin/autologin;then
- b, l' f( a% m: G
exit0
. L& }5 B. s8 ^- Z) G4 F. d
fi
! K2 M$ H/ A, q/ y9 Qfi
]- u7 l: N* w, T: C......
" Y6 H8 B( b5 @1 M& T 不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。
% [: j( Y; `. Z7 X% ^$ l 1、/etc/sysconfig/autologin配置文件的实现:
$ T" K& U; ~2 G( @#configforautologin
0 |: k$ I; Z6 |+ e; b USER=root
; e6 p0 g' `5 ]! W( S/ R5 W EXEC=/usr/X11R6/bin/startx
8 v" b( o1 |1 c# ^2 ^( e 说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。
4 n" O9 ?% V1 [0 j 2、/usr/sbin/autologin可执行文件的实现
' R2 i6 }8 ?( ]' P' B5 F% Z/*********************
8 {. h: ]) m, [% n9 I f
****autologin.c****
5 ?4 y6 {3 \6 y- m" T3 m: }% v*********************/
+ _" q% Y9 a$ J3 [$ a# t* o6 H
#include
7 [+ D6 D- B0 b' Z- K0 J* O% E- R) k5 Z#include
% E2 j8 K$ ^. j
#include
$ O6 c3 h2 ]5 s& g% Z- a#include
' ]9 }8 A4 s' Q#include
; J# n6 R ]$ n y8 T
#include
& R! L1 ~, l/ Y5 Y$ M
#include
9 A; [# o$ U# k3 p4 W4 E6 Z
intmain(intargc,char**argv)
# U* _; F! E5 O) Y; S
{
/ Y& \7 m* D% H; y
structstatst;
5 V4 O. I$ p) L% X9 F0 P; S
FILE*f;
/ w$ a; D% T2 y. w
char*cfg;
! k" c2 A: ?2 y structpasswd*pw;
* L) y7 I9 j5 Y" S5 {) l uid_tuid;
" i* f* s8 U0 s" Y, _ gid_tgid;
5 y- H; y& S# _0 f1 B1 z4 \2 O3 |. g
char*dir,*shell;
8 O8 j# [0 C" @( N8 j char*user=NULL;
) @5 E% n. n/ y1 u6 [ char*cmd=NULL;
6 Y: Y- e' G& O0 n
user="root";
& m7 ^9 C% L/ m& D. n* |$ s* D8 y
/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上,
. `6 N& x1 E+ p: |6 y登陆用户名应该从/etc/sysconfig/autologin中得到,
7 e: W+ q$ I' O2 z程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/
# ^ q# S: ^7 j% Y
cmd="/usr/X11R6/bin/startx";
4 d8 X1 ?' ~" ~, `' P
/*同样,这里直接指定启动XWindow的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/
" W9 i* U$ i) ~$ q! v3 V7 [
[color=#FFFFFF']
/ j: }, ]; t) u1 S! L$ t0 r, f) p; U0 v K) k: K
pw=getpwnam(user);
, B* }* a" B: Y. U$ \" F- m: Z" J
//getpwnam返回包含用户
信息的passwd
结构(该结构在pwd.h中定义)。
' b0 }3 a" ^3 z if(pw){
; R0 p. Z( p7 P0 V7 H3 u uid=pw-%26gt;pw_uid;
/ j2 F: c0 s, q+ }3 k
gid=pw-%26gt;pw_gid; dir=strdup(pw-%26gt;pw_dir);
& g5 k+ R# v( O4 b7 u5 j. E' n4 O
shell=strdup(pw-%26gt;pw_shell);
* I+ }0 A; [# R: M/ N: j }
- [: o' q$ t T! g& {: i/ }5 H //获得用户相关信息
1 q' t. ~/ ]" `8 N5 t
else{
- t& N% R" a" P, X0 q printf("ERROR:Nosuchuser%s!\n",user);
) Y* P5 x( i, b f ~9 B return1;
4 c& [* A' _' X' u }
) E v3 V, H/ q: N' O
chown("/dev/console",uid,gid);
# F9 k8 P1 H& ]5 n4 ?% ] chown("/dev/tty",uid,gid);
) l1 h* Y; C7 b$ f% w //为控制台和终端设置用户ID及组ID
9 k: x, s" p! W) m& u ' z' A4 X0 W: [( F. U
//下面是设置用户相关ID
$ c' x& C8 x- S/ q setregid(gid,gid);
- Z9 q$ U& u) S8 T0 @2 @! I
setegid(gid);
, d2 H5 t3 t. }
setgid(gid);
5 l! {9 b Q3 C# s1 v( ~, h8 p
setreuid(uid,uid);
7 P8 n/ V$ G$ ]* J( v) v- h5 {& K seteuid(uid);
" z0 y$ r! S/ l- I% W8 F6 M$ q* U setuid(uid);
8 Q8 _5 K# K+ t! U K
setenv("HOME",dir,1);
5 l& R. `3 }% B; k/ [2 t8 E setenv("SHELL",shell,1);
6 w8 R5 ?. u* w& p H* @
setenv("USER",user,1);
) e& \! ?: E( E6 y5 T5 C
setenv("LOGNAME",user,1);
" Q4 Z. a1 v, j( \" ]' Y5 |: n
//设置用户相关环境变量
% C( o1 H6 K! J' Z& [' Z5 n" n3 K chdir(dir);
, @. [6 o/ |8 ^6 Q! g
//切换到用户根目录
- S9 I+ H1 S; J user=NULL;
+ u4 Y Q. m. N2 J8 p" k
execvp(cmd,argv);
0 D: C4 b% }6 ~3 T
/*在配置完用户的相关信息后,执行启动XWindow操作。注意这里默认执行/usr/X11R6/bin/startx*/
8 J: \" a8 Q0 p% v printf("ERROR:Couldn'texec%s:%s\n",cmd,strerror(errno));
! n- ?2 j- N9 D" S) m& h* L& A' y
return2;
: X1 t9 D8 s0 s4 |0 o8 `% \}
4 \5 T Z. x9 B[color=#FFFFFF']
- ?# @/ o" P, @9 E$ V
3 g$ g0 Z& t+ y; R* L/ g3 K 运行gcc-oautologinautologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。重新启动系统,会直接进入XWindow并保留用户原来所有的风格。
/ `& g" x. o. J( W w' J# k
$ }7 `8 n4 V- O. R6 k: c, | 如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下:
: i0 E- U$ v! p
......
2 m1 V1 k3 E, d4 r#第一步:查看是否为自动登录
+ M. {( m9 D* {6 E9 K0 B8 b
if/usr/sbin/autologin;then
% ` q8 ]/ F5 Y8 e- S( `
exit0
' g& G% E: z- M fi
) \2 P: ]5 P3 E0 S `# a& A. J //第二步 ......
% K( u8 p p+ n6 a! f1 C
......
- |2 r2 Q( G ^, @
即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。
3 `/ U' V& w& {2 ^3 O! V5 A2 v- t
四、选择进入kde或者gnome,并自动启动XWindow应用程序
( E5 j7 z" o9 _% l 如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdeskgnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。一般系统自动登录的目的是启动XWindow后自动运行某个XWindow程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在XWindow启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startupprograms属性页中即可。