代码:
#!/bin/sh userclientrc=$HOME/.xinitrc #用户的client定义文件 userserverrc=$HOME/.xserverrc #用户的server定义文件 sysclientrc=/usr/X11R6/lib/X11/xinit/xinitrc #系统的client sysserverrc=/usr/X11R6/lib/X11/xinit/xserverrc #系统的server defaultclient=/usr/X11R6/bin/xterm #默认的client程序 defaultserver=/usr/X11R6/bin/X #默认的server程序 defaultclientargs="" #下面定义了client和server的参数变量 defaultserverargs="" clientargs="" serverargs="" #如果用户client文件存在则使用用户文件里定义的client,否则使用系统定义的client if [ -f $userclientrc ]; then defaultclientargs=$userclientrc elif [ -f $sysclientrc ]; then defaultclientargs=$sysclientrc fi #如果用户server文件存在则使用用户文件里定义的server,否则使用系统定义的server if [ -f $userserverrc ]; then defaultserverargs=$userserverrc elif [ -f $sysserverrc ]; then defaultserverargs=$sysserverrc fi #下面循环处理client和server的参数 whoseargs="client" while [ x"$1" != x ]; do #若第一个参数为空,退出循环 case "$1" in # '' required to prevent cpp from treating "/*" as a C comment. /''*|\./''*) #如果$1是/*或者./*形式(xinit程序要求其参数里的client程序和server程序必须以/或./开头,否则会被视为client程序和server程序的参数,见man xinit) if [ "$whoseargs" = "client" ]; then #如果当前是在处理client的参数 if [ x"$clientargs" = x ]; then #如果clientargs为空,则赋值$1给client变量,也即上面#startx使用方法里的[client]参数 client="$1" else clientargs="$clientargs $1" #否则clientargs赋值为$clientargs $1,即上面#startx使用#方法里的options参数 fi else #当前在处理server的参数,代码的含义同上 if [ x"$serverargs" = x ]; then server="$1" else serverargs="$serverargs $1" fi fi ;; --)#如果$1为--,则表示开始处理server的参数,--为client和server参数的分界 whoseargs="server" ;; *) if [ "$whoseargs" = "client" ]; then #处理给client程序的参数 clientargs="$clientargs $1" else #处理给server程序的参数 # display must be the FIRST server argument #屏幕编号必须为第一个给server程序的参数,以:x的形式(x为数字),这可从上面startx和xinit 的使用方法的区别看出,xinit多了个[display],这里即过滤出这个[display]。试试看这两个命令: xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X :1 -dpi 70& xinit /usr/bin/X11/xeyes -display localhost:1 -- /usr/bin/X11/X -dpi 70 :1& 即可看出不把屏幕编号作为第一个server参数的后果 if [ x"$serverargs" = x ] && expr "$1" : ':[0-9][0-9]*$' > /dev/null 2>&1; then
display="$1" else #处理屏幕编号以外的参数 serverargs="$serverargs $1" fi fi ;; esac shift #所有参数左移一次 done # process client arguments if [ x"$client" = x ]; then #如果client程序为空 # if no client arguments either, use rc file instead if [ x"$clientargs" = x ]; then #且clientargs为空,赋值$defaultclientargs给client程序 client="$defaultclientargs" else client=$defaultclient #使用默认的client程序 fi fi # process server arguments处理server参数,同上 if [ x"$server" = x ]; then # if no server arguments or display either, use rc file instead if [ x"$serverargs" = x -a x"$display" = x ]; then server="$defaultserverargs" else server=$defaultserver fi fi #…………省略授权代码若干
但还未搞清楚gnome是怎么起来的!gnome当然属于X client了,看上面启动过程第(3)步。
这里分两种情况看吧,第一种是用系统的xinitrc文件。看/etc/X11/xinit/xinitrc文件(我的sarge装x-window-
system-core和gnome-core),里面只包含了.
/etc/X11/Xsession一句话。接着看/etc/X11/Xsession这个脚本,只看关键部分吧。最后面有:
[code]
SESSIONFILES=$(run_parts $SYSSESSIONDIR)
if [ -n "$SESSIONFILES" ]; then
for SESSIONFILE in $SESSIONFILES; do
. $SESSIONFILE
done
fi
exit 0
[code]
接着看run_parts(),位于本文件中间:
代码:
run_parts () { # until run-parts --noexec is implemented if [ -z "$1" ]; then internal_errormsg "run_parts() called without an argument." fi if [ ! -d "$1" ]; then internal_errormsg "run_parts() called, but \"$1\" does not exist or is" \ "not a directory." fi for F in $(ls $1); do if expr "$F" : '[[:alnum:]_-]\+$' > /dev/null 2>&1; then if [ -f "$1/$F" ]; then echo "$1/$F" fi fi done }
大 概意思就是run_parts ()
把$SYSSESSIONDIR目录下的文件名取出来赋值给$SESSIONFILES,然后循环运行该目录下的文件。看看该目录,即
/etc/X11/Xsession.d目录,可以看到几个以数字开头的文件,实际上这些数值就表示了这几个文件被运行的优先级,数字小的优先级高,因为
在上面的run_parts () 里是用ls命令显示该目录下的文件,所以前面数字小的被ls时显示在前面,所以被
代码:
for SESSIONFILE in $SESSIONFILES; do . $SESSIONFILE done
这个for循环执行时也先被执行。看到/etc/X11/Xsession.d目录下有个55gnome-session_gnomerc文件,里面提到了STARTUP变量。然后运行:
xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
看到50xfree86-common_determine-startup文件。里面有
代码:
if [ -z "$STARTUP" ]; then if [ -x /usr/bin/x-session-manager ]; then STARTUP=x-session-manager elif [ -x /usr/bin/x-window-manager ]; then STARTUP=x-window-manager elif [ -x /usr/bin/x-terminal-emulator ]; then STARTUP=x-terminal-emulator fi fi
即设置启动程序,实际上设置STARTUP变量,如果以上程序都没有找到,则会报错退出,即X环境没有被启动。再运行
xdkui@Debian:/etc/X11/Xsession.d$ grep STARTUP *
看到优先级最低也即最后被运行的99xfree86-common_start文件,里面只有一句话:
exec $STARTUP
好了,到这里就启动我们的X
client了,终于完了^_^。总结下这第一种方式的启动过程,简单的说就是依次顺序查找/usr/bin/x-session-manager
,x-window-manager,/usr/bin/x-terminal-emulator 这三个文件。如果存在则启动之,也即X
client。如果三个都不存在则报错退出了。看/usr/bin/x-session-manager文件可以看到是个符号连接,最终连接到
/usr/bin/gnome-session,也就是gnome 了。至于我们在gnome
启动时可能会设置启动输入法等程序,那就归gnome-session管了,也就不再分析了。可以试着把/usr/bin/x-session-
manager 改为指向xfce4-session(如果安装了的话)
,再startx就会启动xfce4环境了。大概RedHat的switchdesk工具就是改这个连接实现的吧?。或者删掉/usr/bin/x-
session-manager ,再startx,只启动了/usr/bin/x-window-manager 所指向的window
manager了吧,我这里是blackbox。