标签:des http 使用 os strong 文件 数据 io
以下看看/usr/bin/startx这个脚本。
#!/bin/bash
#
# This is just a sample implementation of a slightly less primitive
# interface than xinit. It looks for user .xinitrc and .xserverrc
# files, then system xinitrc and xserverrc files, else lets xinit choose
# its default. The system xinitrc should probably do things like check
# for .Xresources files and merge them in, startup up a window manager,
# and pop a clock and serveral xterms.
#
# Site administrators are STRONGLY urged to write nicer versions.
#
unset DBUS_SESSION_BUS_ADDRESS
unset SESSION_MANAGER
userclientrc=$HOME/.xinitrc # 用户的client定义文件
sysclientrc=/etc/X11/xinit/xinitrc # 系统的client定义文件
userserverrc=$HOME/.xserverrc # 用户的server定义文件
sysserverrc=/etc/X11/xinit/xserverrc # 系统的server定义文件
defaultclient=xterm # 默认的client程序
defaultserver=/usr/bin/X # 默认的server程序
defaultclientargs="" # 以下定义了client和server的參数变量
defaultserverargs=""
defaultdisplay=":0"
clientargs=""
serverargs=""
enable_xauth=1
# 參数解析:将whoseargs变量赋值为字符串“client”,表示当前解析的指定client的參数
whoseargs="client"
while [ x"$1" != x ]; do # 若第一个參数为空,则直接退出循环
case "$1" in
# 须要单引號‘‘以避免cpp把"/*"当作凝视
/‘‘*|\./‘‘*) # 假设$1是/*或者./*形式 (xinit程序要求其指定的client程序和server程序必须以/或./开头,
# 否则会被视为client程序和server程序本身的options參数,见man xinit)
if [ "$whoseargs" = "client" ]; then # 解析client程序的參数
if [ x"$client" = x ] && [ x"$clientargs" = x ]; then
client="$1" # 解析出用户指定的client程序
else
clientargs="$clientargs $1" #解析出client程序的options參数
fi
else
if [ x"$server" = x ] && [ x"$serverargs" = x ]; then
server="$1" # 解析出用户指定的X server程序
else
serverargs="$serverargs $1" # 解析出X server的options參数
fi
fi
;;
--) # 遇到“- -”就解析server
whoseargs="server"
;;
*)
if [ "$whoseargs" = "client" ]; then
clientargs="$clientargs $1"
else
# 解析[display]參数,屏幕编号[display]必须为第一个给server程序的參数,以:x的形式(x为数字)
if [ x"$serverargs" = x ] && expr "$1" : ‘:[0-9][0-9]*> /dev/null 2>&1; then
display="$1"
else
serverargs="$serverargs $1" # 解析[display]以外的參数
fi
fi
;;
esac
shift # 全部參数左移一次
done
# 处理client參数
if [ x"$client" = x ]; then # 假设用户没有指定X client,则使用默认的X client即xterm
client=$defaultclient
# 假设没有client的选项參数,则用rc文件取代
if [ x"$clientargs" = x ]; then
if [ -f "$userclientrc" ]; then
client=$userclientrc
elif [ -f "$sysclientrc" ]; then
client=$sysclientrc
fi
clientargs=$defaultclientargs
fi
fi
# 处理server參数
if [ x"$server" = x ]; then # 假设用户没有指定X server,则使用默认的X server即X
server=$defaultserver
# 假设没有server的选项參数或display參数,使用默认值
if [ x"$serverargs" = x -a x"$display" = x ]; then
# 为了兼容性的考虑,假设没有server的命令行參数,仅仅使用xserverrc文件
if [ -f "$userserverrc" ]; then
server=$userserverrc
elif [ -f "$sysserverrc" ]; then
server=$sysserverrc
fi
serverargs=$defaultserverargs
display=$defaultdisplay
fi
fi
if [ x"$enable_xauth" = x1 ] ; then
if [ x"$XAUTHORITY" = x ]; then # 假设环境变量XAUTHORITY为空,就设定为$HOME/.Xauthority
XAUTHORITY=$HOME/.Xauthority
export XAUTHORITY
fi
removelist=
# 设置本机的默认Xauth信息
# 检查GNU主机名,假设hostname –version中不包括GNU 就将hostname变量设定为命令hostname –f返回的字符串
if hostname --version > /dev/null 2>&1; then
if [ -z "`hostname --version 2>&1 | grep GNU`" ]; then
hostname=`hostname -f`
fi
fi
if [ -z "$hostname" ]; then
hostname=`hostname`
fi
authdisplay=${display:-:0}
mcookie=`/usr/bin/mcookie`
if test x"$mcookie" = x; then
echo "Couldn‘t create cookie"
exit 1
fi
dummy=0
# 为server创建带有auth信息的文件,假设为屏幕编号为‘:0‘
xserverauthfile=`mktemp --tmpdir serverauth.XXXXXXXXXX`
trap "rm -f ‘$xserverauthfile‘" HUP INT QUIT ILL TRAP KILL BUS TERM
xauth -q -f "$xserverauthfile" << EOF
add :$dummy . $mcookie
EOF
serverargs=${serverargs}" -auth "${xserverauthfile}
# now add the same credentials to the client authority file
# if ‘$displayname‘ already exists do not overwrite it as another
# server man need it. Add them to the ‘$xserverauthfile‘ instead.
for displayname in $authdisplay $hostname$authdisplay; do
authcookie=`xauth list "$displayname" | sed -n "s/.*$displayname[[:space:]*].*[[:space:]*]//p"` 2>/dev/null;
if [ "z${authcookie}" = "z" ] ; then
xauth -q << EOF
add $displayname . $mcookie
EOF
removelist="$displayname $removelist"
else
dummy=$(($dummy+1));
xauth -q -f "$xserverauthfile" << EOF
add :$dummy . $authcookie
EOF
fi
done
fi
# #以下的语句通过xinit启动X server和Clients,把处理的參数传给它
xinit "$client" $clientargs -- "$server" $display $serverargs
retval=$?
if [ x"$enable_xauth" = x1 ] ; then
if [ x"$removelist" != x ]; then
xauth remove $removelist
fi
if [ x"$xserverauthfile" != x ]; then
rm -f "$xserverauthfile"
fi
fi
exit $retval
以上即为X Window System的启动过程,startx仅仅是负责一些參数传递,真正的X启动由xinit实现。我们能够知道,startx将会先解析用户的參数,假设该用户指定了该參数(即解析结果不为空),那么startx就会以该參数来启动xinit,否则就会解析(与其说是解析,还不如说是运行)$HOME文件夹下的rc文件,假设该文件不存在,就会解析系统文件夹下(/etc/X11/xinit/)的rc文件,假设这个文件也不存在,那startx就将以默认的client(xterm)和server(/usr/bin/X)为參数来启动xinit。比如,能够在用户文件夹下构造.xinitrc(即X
client)和.xserverrc(即X server)文件。在.xserverrc里写入/usr/bin/X11/X :1。.xinitrc里写入/usr/bin/X11/xeyes -display localhost:1。这就是最简单的X server+ X client了,仅仅只是把屏幕编号从默认的0改为了1。
到眼下为止,我们还不知道只在终端输入startx是怎么样启动gnome桌面的,gnome当然属于X client了。通过对startx的分析可知,startx主要有三种启动方式:
(1)一种是自己指定要启动的client和server, 比如:startx /usr/bin/xclock -- /usr/bin/X :0;
(2)一种是通过在$HOME下新建.xinitrc文件来指定要启动的多个client和.xserverrc来指定要启动的server(注意:这两个文件本来是不存在的);
(3)另一种是直接输入startx而不指定參数,这也就是我们启动gnome桌面的方法。
在第(3)中启动方法中,我们能够知道,startx脚本会先去看系统文件夹(/etc/X11/xinit/)下的rc文件是否存在,假设不存在就会用默认的xterm和/usr/bin/X来启动xinit。显然,startx启动的不是xterm,而是gnome桌面,因此gnome的启动是通过系统文件/etc/X11/xinit/xinitrc来指定的。在“Linux init程序分析”中具体介绍过的gnome的启动。这里以Ubuntu为例,/etc/X11/xinit/xinitrc文件里仅仅包括了. /etc/X11/Xsession一句话,因此gnome是通过Xsession脚本启动的(在Fedora中则是直接用xinitrc来启动gnome)。以下是Xsession文件:
#!/bin/sh # 注意该脚本用的是Bourne shell解析的
#
# /etc/X11/Xsession
#
# global Xsession file -- used by display managers and xinit (startx)
# $Id: Xsession 967 2005-12-27 07:20:55Z dnusinow $
set -e # 打开errexit选项,该选项表示假设以下有命令返回的状态非0,则退出程序
PROGNAME=Xsession
# 以下4个是信息输出函数,能够无论
message () {
# pretty-print messages of arbitrary length; use xmessage if it
# is available and $DISPLAY is set
MESSAGE="$PROGNAME: $*"
echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2
if [ -n "$DISPLAY" ] && which xmessage > /dev/null 2>&1; then
echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
fi
}
message_nonl () {
# pretty-print messages of arbitrary length (no trailing newline); use
# xmessage if it is available and $DISPLAY is set
MESSAGE="$PROGNAME: $*"
echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2;
if [ -n "$DISPLAY" ] && which xmessage > /dev/null 2>&1; then
echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
fi
}
errormsg () {
# exit script with error
message "$*"
exit 1
}
internal_errormsg () {
# exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
# One big call to message() for the sake of xmessage; if we had two then
# the user would have dismissed the error we want reported before seeing the
# request to report it.
errormsg "$*" "Please report the installed version of the \"x11-common\"" "package and the complete text of this error message to" "<debian-x@lists.debian.org>."
}
# 初始化被全部session脚本使用的变量
OPTIONFILE=/etc/X11/Xsession.options
SYSRESOURCES=/etc/X11/Xresources
USRRESOURCES=$HOME/.Xresources
SYSSESSIONDIR=/etc/X11/Xsession.d
USERXSESSION=$HOME/.xsession
USERXSESSIONRC=$HOME/.xsessionrc
ALTUSERXSESSION=$HOME/.Xsession
ERRFILE=$HOME/.xsession-errors
# 尝试创建一个error文件,假设不能创建则退出
if (umask 077 && touch "$ERRFILE") 2> /dev/null && [ -w "$ERRFILE" ] &&
[ ! -L "$ERRFILE" ]; then
chmod 600 "$ERRFILE"
elif ERRFILE=$(tempfile 2> /dev/null); then
if ! ln -sf "$ERRFILE" "${TMPDIR:=/tmp}/xsession-$USER"; then
message "warning: unable to symlink \"$TMPDIR/xsession-$USER\" to" "\"$ERRFILE\"; look for session log/errors in" "\"$TMPDIR/xsession-$USER\"."
fi
else
errormsg "unable to create X session log/error file; aborting."
fi
# 截短ERRFILE,假设它太大了,以避免硬盘空间的DoS攻击
if [ "`stat -c%s \"$ERRFILE\"`" -gt 500000 ]; then
T=`mktemp -p "$HOME"`
tail -c 500000 "$ERRFILE" > "$T" && mv -f "$T" "$ERRFILE" || rm -f "$T"
fi
exec >>"$ERRFILE" 2>&1
echo "$PROGNAME: X session started for $LOGNAME at $(date)"
# 理智的检查:#假设/etc/X11/Xsession.d不存在或不是一个文件夹则打印错误信息并退出
if [ ! -d "$SYSSESSIONDIR" ]; then
errormsg "no \"$SYSSESSIONDIR\" directory found; aborting."
fi
# Attempt to create a file of non-zero length in /tmp; a full filesystem can
# cause mysterious X session failures. We do not use touch, :, or test -w
# because they won‘t actually create a file with contents. We also let standard
# error from tempfile and echo go to the error file to aid the user in
# determining what went wrong.
WRITE_TEST=$(tempfile)
if ! echo "*" >>"$WRITE_TEST"; then
message "warning: unable to write to ${WRITE_TEST%/*}; X session may exit" "with an error"
fi
rm -f "$WRITE_TEST"
# use run-parts to source every file in the session directory; we source
# instead of executing so that the variables and functions defined above
# are available to the scripts, and so that they can pass variables to each
# other
SESSIONFILES=$(run-parts --list $SYSSESSIONDIR) # 将/etc/X11/Xsession.d文件夹中的全部文件都读出,并存入SESSIONFILES变量中
if [ -n "$SESSIONFILES" ]; then
set +e # 关闭errexit选项
for SESSIONFILE in $SESSIONFILES; do # 运行Xsession.d下的每个脚本
. $SESSIONFILE
done
set -e
fi
exit 0
# vim:set ai et sts=2 sw=2 tw=80: 从以上的对Xsession脚本文件的分析,能够看出,Xsession脚本不过运行了/etc/X11/Xsession.d文件夹下的全部文件,每个文件名称都以数字开头,这些数字就表示了文件被运行的优先级,数字小的优先级高,run-parts会将数字小的排在前面,这样就能确保以上文件能按数字由小到大的顺序运行。基本的文件例如以下:/usr/bin/startx --->xinit /etc/X11/xinit/xinitrc -- /etc/X11/xinit/xinitrc --->./etc/X11/Xsession --->/etc/X11/Xsession.d/ --->50x11-common_determine-startup --->/etc/X11/Xsession.options # 寻找相关配置选项 --->STARTUP=$HOME/.xsession # 假设有.xsession脚本,则设置成执行它 --->STARTUP=/usr/bin/x-session-manager # 假设没有.xsession脚本,则设置成执行x-session-manager --->/usr/bin/gnome-session # x-session-manager指向gnome-session程序 --->55gnome-session_gnomerc --->$HOME/.gnomerc # 选择了gnome-session,则执行$HOME/.gnomerc --->75dbus_dbus-launch # 启动dbus --->80im-switch # 设置输入法 --->99x11-common_start --->exec $STARTUP # 启动gnome会话,进入gnome桌面3、跨网络执行X Window System
X Window System介绍,布布扣,bubuko.com
标签:des http 使用 os strong 文件 数据 io
原文地址:http://www.cnblogs.com/mfrbuaa/p/3866293.html