当前位置:Linux教程 - Linux - Xdm会话进程

Xdm会话进程

By Chris Carlson 翻译: 程剑峰

在安装好系统中的X窗口系统后,只要把系统默认的启动模式设置成模式5,系统在启动时就会自动运行xdm。现在我们应该考虑该如何设置xdm,使它在我们登录进入系统时能自动启动一些应用程序。

在单位里,我每天回家前总是要退出系统,因为当我不在时,其他人也可能会来使用机器。我可不希望其他人在我的办公室里用我的帐号登陆到机器上,虽然这样的事并不常有。(也许会有人出于好奇想翻翻我存在硬盘上的邮件。)现在的问题是,我希望在我登录进入系统时,Xdm可以自动启动一些应用程序,比如我的记事簿和我的日历程序等。

在这篇文章中我打算讨论一些关于X窗口中的会话进程的东西:它是怎么启动的,如何对它进行定制。我要告诉你怎样让系统在启动时自动启动你喜欢的Window管理器(Window Manager),怎样让Xdm自动启动应用程序,怎样用你喜欢的字体和颜色设置X环境。由于所有UNIX平台上的X Window系统都差不多,所以以下的内容不仅适用于Linux上的XFree86系统,也适用于其他平台上的X Window系统。事实上,我会对Redhat 5.x中的XFree86和SGI IRIX中的X Window系统进行比较。你会发现在这两个系统中我们用到的文件都使用相同的文件名,只是在不同的目录下。

我知道其他人已经写了一些有关X Window配置的文章,比如在十二月的那期(译者注:英文原版linux公报的期号)有一篇Jay Ts写的“X Window管理”。虽然X Windows是非常通用的,可它也是非常复杂的。我认为有关X Window的东西足够写很多文章。这些文章的内容可能有一部份是重复的,但每篇文章都可以从不同的角度来写。我的这篇文章尽可能从一个用户而不是一个管理员的角度来写。

这篇文章的内容是基于以下几个前提条件的:

系统中的xdm使用Red Hat的默认设置。也就是说你没有改过/etc/X11/xdm目录下的任何文件。(由于我没有安装过其他的Linux,我假设它们的默认设置也和Red Hat的一样,或者他们间虽有差别,但不影响我们这里讨论的内容。)考虑到这些情况,对于那些xdm用到的文件,我就直接使用系统默认的文件名。应当注意的是,大多数的文件名我们都可以自己加以修改的,比如你可以改动/etc/X11/xdm/xdm-config文件,或者在启动xdm时通过命令行指定其他的配置文件。(在SGI上,设置文件为/var/X11/xdm/xdm-config,我见过其他的一些系统使用/usr/lib/X11/xdm/xdm-config。)
你对X Window使用的客户/服务器的概念应该有一个基本的了解。即X服务器是一个程序,处理显示和键盘输入。其他应用程序作为客户使用X服务器提供的服务进行显示和读取输入。
你对X资源及其在X环境中的用途有一定的了解。
用户会话的初始化和终止

X服务器通过xdm启动后出现用户登录屏幕。用户从这个屏幕成功登录以后,xdm实际上就成功的启动了一个“用户会话”。这个会话是一个shell脚本(shell script)。这个脚本终止时就会终止用户会话,同时xdm会结束X服务器,并使系统回到用户登录状态。
在开始一个X会话之前,xdm会用超级用户(root)的权限运行一个启动脚本以执行一些必需的初始化。随后,为了保证以当前用户的环境设置运行X Window,脚本文件/etc/X11/xdm/GiveConsole将把/dev/console的拥有者从root改回到当前用户。

同样的,当会话结束时xdm会首先以超级用户的权限执行一个小脚本来清除由启动脚本创建的东西。然后由脚本/etc/X11/xdm/TakeConsole将/dev/console的拥有权改回超级用户。

请注意在SGI上这两个文件分别是/var/X11/xdm/GiveConsole和/var/X11/xdm/TakeConsole

在这篇文章中我们感兴趣的是这个用户会话本身的启动过程。在这个过程中,xdm启动一个子进程运行脚本/etc/X11/xdm/Xsession(在SGI上是/var/X11/xdm/Xsession)并等待其退出。当这个子进程退出时,xdm就会运行退出脚本并回到登录屏幕。这个会话脚本是运行在当前用户权限下的。

在xdm,当用户输完密码后,按F1键而不是Enter键时,xdm会将参数“failsafe”传递给用户会话。这在由于用户对其会话脚本文件进行了错误的修改而不能正常登录进入系统时显得非常有用。在下文中我会详细讨论如何利用这一特性。应当注意到,在Linux和SGI中这一用法都是一样的。

Xsession文件

Red Hat中提供的/etc/X11/xdm/Xsession文件相当简单,特别是和SGI中的/var/X11/xdm/Xsession相比时更是如此。这个文件是标准的shell脚本,用于处理所有用户的X启动和初始化。系统管理员可以将各用户初始化文件中一致的部分放在此文件中。
在前面已经提到,用户登录时如果按F1键而不是Enter键,系统会传递参数“failsafe”给会话进程。/etc/X11/xdm/Xsession文件在运行时,首先检查该参数是否存在。如果有此参数,就调用exec来执行xterm。这样就会跳过所有的用户初始化而直接进入一个终端窗口。应当注意到当用户错误地改动了自己的个人会话环境文件而导致不能正常登录时,这是一个很好的登录方法。

对于那些不了解exec的功能的读者,这里对exec进行一点解释:exec是所有标准的shell程序都提供的内部命令。它使用调用的程序代替当前正在运行的shell。所以exec永远不会返回到当前正在运行的shell中(除非被调用的程序由于某些原因而无法启动),同时父进程也不知道子进程中发生的任何变化。被exec调用的程序拥有shell的进程ID,当该程序结束时shell也就结束了,并结束用户会话。

如果Xsession没有收到“failsafe”参数,脚本将stderr重定向到一个错误日志文件并继续执行。这个文件就是用户home目录下的.xession-errors文件。如果系统不能在用户的home目录下建立该文件或者该文件由于某种原因而导致系统无法对它进行写入操作,脚本就会试着使用/tmp/xses-$USER文件。$USER是用户的登录名。

这个错误文件对于判断用户会话中的问题非常有用。所有应用程序(包括窗口管理器和窗口管理器启动的应用程序)产生的错误信息都会写入该文件中。如果用户在登录进入系统后不能启动一个用户会话,他就可以使用“failsafe”的办法(参见上文)登录,然后检查这个文件中的出错信息。这些出错信息对于我们寻找问题所在是很有帮助。

启动用户会话成功后,标准的Xsession文件会将控制权传给一组shell脚本中的某一个。具体使用哪个文件要根据用户具体情况决定。由于它是使用exec来调用这些文件的,因此一旦被调用程序开始运行,它就成为一个新的用户会话并替代掉Xsession进程。这些shell脚本包括:

$HOME/.xsession
$HOME/.Xclients
/etc/X11/xinit/Xclients
SGI在对脚本的处理上和Linux稍有不同。SGI不要求脚本是可执行的。如果这些脚本是不可执行的,系统会调用/bin/sh来运行这些程序。同时SGI只检查$HOME/.xsession。如果没有这个文件,系统的Xsession文件就会建立一个SGI内置的默认用户环境。RedHat则把用户会话环境分成两个部分,它在系统按照标准方式安装时,就提供了一个/etc/X11/xinit/Xclients文件。
如果以上的三个文件都不存在或者不可执行,系统会尝试读取用户的.Xresources文件(如果有该文件的话),并调用exec执行xsm。xsm是RedHat Linux提供的多个窗口管理器之一。

用户定制的Xsession文件

从上面对系统Xsession文件的解释中你可能已经猜到用户可以创建自己的shell脚本。这是一个非常强大的功能,允许每个用户决定每次从X登录进入系统后系统可以先自动进行哪些操作。在这个脚本中,用户可以启动多个应用程序、设置X Window主窗口(root window)的资源环境、设置系统环境变量、修改默认的键盘定义以及选择一个窗口管理器等。
设置你个人的Xsession文件的最简单的方法是把系统的/etc/X11/xinit/Xclients文件拷贝到你的home目录下,命名为.xsession或.Xclients(在下文中用用户的Xsession文件表示)并根据需要进行修改。在这里,我不打算解释/etc/X11/xinit/Xclients文件中的所有内容含义。我只想解释那些可能用到的东西。

一个很重要的事就是装载X Window主窗口需要的资源。这通常由以下的命令实现:

resources=$HOME/.Xresources
if [ -f ""$resources"" ]; then
/usr/bin/X11/xrdb -load ""$resources""
fi
另外一件用户常做的事是修改用户主窗口的背景图案。这可以用/usr/bin/X11/xsetroot命令实现。我是这么设置背景图案的:
/usr/bin/X11/xsetroot -solid DarkSeaGreen4
这个命令也可以用于设置主窗口的默认光标和光标的颜色。背景图案既可以用一个双色的格子图案也可以使用一个X位图。
同样的,/usr/bin/X11/xset命令可以用来设置喇叭的音量、击键、DPMS(节能)特性和鼠标的参数。这个命令还能设置自动重复和屏幕保护的参数。

如果你想定义特殊键,你可以在脚本中运行/usr/bin/X11/xmodmap。比如我想要使用完全的ISO 8859-1字符集,并在我的文件中插入国际字符,由于linux已经F1和F2分别定义为F11和F12,而我的键盘上有F11和F12键,所以我希望把这些键分别定义为F13和F14。为了达到这个目的,我在$HOME/.xmodmaprc中加入了以下内容:

keycode 113 = Multi_key
keysym F1 = F1 F13
keysym F2 = F2 F14
keysym F3 = F3 F15
...
keysym F10 = F10 F22
keycode 95 = F11 F23
keycode 96 = F12 F24
然后我在$HOME/.xsession文件中加入以下内容:
if [ -r $HOME/.xmodmaprc ]; then
/usr/bin/X11/xmodmap $HOME/.xmodmaprc
fi
最后,最重要的一步是选择自己喜欢的窗口管理器。RedHat默认的是运行fvwm,因为它可以设置成看起来和Windows 95差不多。由于我经常使用SGI计算机,我更喜欢Motif(不是免费的,通常不随Linux提供)。可供选择的还有xsm和twm。你可以读读它们的使用说明然后再决定使用哪个。
用户可以在Xsession文件的末尾用exec命令来调用窗口管理器。这样用户只有退出窗口管理器才能终止他们的X会话以重新回到登录屏幕。相对而言,我更喜欢将窗口管理器当作后台进程运行,并在Xsession文件的末尾使用exec来调用xterm。这样当我退出xterm会话时用户会话就会终止并回到登录屏幕。要注意,在这种情况下,由于X Window将被关闭,所以此时窗口管理器和所有窗口程序都会终止,但是所有那些作为后台进程运行的非窗口程序是不会自动终止的,在X用户会话结束后他们还会继续运行。

这是我启动Motif窗口管理器的方法:

/usr/bin/X11/mwm
这是最后的xterm:
exec nxterm -geometry 80x50+10+10 -ls
这样可以使运行的xterm支持彩色。它每行可显示80个字符,共显示50行。窗口会定位在屏幕的左上角(在10x10象素的位置)。最后的那个选项是让nxterm把shell当作登录shell来运行。
在用户的Xsession文件里,你可以运行许多的xterm, xclock或其他程序。所有的这些程序都会在你登录时自动启动。如果你希望这些程序固定在屏幕上的某些位置,别忘了定义程序窗口的坐标(使用-geometry选项)。

还有,记着让这些程序在后台执行(以“&”结尾)。否则用户的Xsession文件会等到这些程序终止后才继续执行下一行命令。

重要的窍门

在这里我想讨论用户Xsession文件中的一些有趣并且重要的窍门。
所有的窗口管理器都可以通过下拉选单中调用应用程序。有些应用程序需要在运行之前设置一些环境变量(比如Netscape需要定义SOCKS_NS)。由于一般来说用户的环境变量是在shell启动后才设置的,所以窗口管理器和窗口管理器中启动的程序将无法设置这些用户环境变量。在$HOME/.cshrc,$HOME/.profile或$HOME/.login中设置这些变量也是不可能的。

一个窍门就是在用户的Xsession文件中设置这些变量。在你启动窗口管理器前设置这些变量是必要的。

我喜欢用的另一个窍门就是在我的用户Xsession文件中定义XUSERFILESEARCHPATH变量。大多数应用程序在启动时需要一个程序资源文件,这些文件多半在/usr/lib/X11/app-defaults下。比如Netscape就使用/usr/lib/X11/app-defaults/Netscape来存放程序的资源设置。如果你想在自己的个人环境中修改设置,你可以将此文件拷贝到你的home目录下加以修改。下次你运行Netscape时它就会根据你Home目录下的那个文件进行设置。

我发现我的home目录下挤满了各种应用程序的资源文件。我想把这些文件放到我自己的app-default目录下。于是我就建立了这个目录并把所有的资源文件到拷贝进去。然后我在我的用户Xsession文件中设置XUSERFILESEARCHPATH变量:

/home/carlson/app-defaults/%N:/usr/lib/X11/%L/app-defaults/%N:/usr/lib/X11/app-defaults/%N
这就可以让应用程序先到/home/carlson/app-defaults里寻找程序资源文件,然后才是默认的/usr/lib/X11。
最后一个窍门是给那些有好几台运行X服务器的计算机的人。在家里,我有一台SGI O2和我的Linux机器。当我远程登录进入O2时,我希望能够运行X应用程序并把输出显示在我的Linux上。为此我需要在每次登录进入Linux系统后运行xhost以允许远程登录使用X服务器。

在我的用户Xsession文件中有这一行:

/usr/bin/X11/xhost +moonlight
这使得我的Linux系统中的X服务器允许来自moonlight(我的那台O2)的访问。
结论

我希望你觉得本文对你有一定帮助。我尽力向你展示如何建立你自己的用户Xsession文件来运行程序,设置环境以及运行你自己的窗口管理器。我相信你自己也可以想出更多的好点子。
我根据SGI上的一个程序写了个很有用的程序userenv。这个程序创建一个登录shell做为子进程,并让其输出它的环境。这些环境变量以特定格式输出到stdout上以便于使用shell创建一个相同的环境。

在我的用户Xsession文件中有这么一行:

eval ``userenv``
这行命令会检查我计算机当前的用户环境并以一种shell可以识别的格式输出它。用户使用这些输出数据就可以让shell在其他机器上创建一个相同的用户环境。eval命令是将输出结果送给shell处理。
你可以从我的网站下载eval程序,它在http://members.home.net/cwcarlson/files/utilities.tar.gz





我用的是RedHat 5.1,但它好象最近几年并没有什么大的变化。同时我也发现在IRIX等其他的Unix平台上设置这些东西和Linux下差不多一样。唯一的区别是文件放在不同的目录下而已。