dbus和KDE的集成:使用KDM启动和停止dbus的会话部分。
内容
介绍
1.调整KDM的配置
2.启动dbus的sessiondaemon并使环境变量可用。
关于Bash的启动文件。
2.2启动dbus的sessionbus部分
2.3停止dbus的sessionbus部分
2.4一个用户登录不止一次
介绍
由于现在很多应用程序都使用D-BUS。这是KDE 3.5的情况,目前KDE的稳定版本。随着KDE 4的上升,D-BUS越来越重要,取而代之的是DCOP。
在这个方面,我想描述一种启动和停止dbus的用户和会话依赖部分的方法。我用这种方法考虑的主要目标是:
- 使d-bus感知应用程序的环境变量非常重要;
- 确保一个用户不要多次启动dbus sessionpart;
- 当用户的会话结束时,确保dbus会话部分已停止;
我假设用户使用KDM登录,KDE 3.5的登录管理器。该建设也可以很好地与其他登录管理员(XDM,GDM)一起使用。
KDM可以在会话开始时(启动时)和结束(重置)运行脚本。其中一个可以启动(并停止)dbus会话部分。
KDM:文件
KDM使用一些文件来启动和停止:
。 Xstartup
在用户成功登录后运行。
。 Xsession
以授权用户的权限运行,启动所需的会话(KDE)。
。 Xreset
在用户会话结束后以root身份运行。
在Xstartup是启动的地方,Xreset是撤销这些命令的地方。
有关这些文件的更多信息,请参阅KDM 手册 。
通过将以下代码添加到Xstartup文件中:
-- snip -- for script in /etc/session.d/kdm/startup/*.sh; do if [ -x $script ]; then eval $script $USER kdm fi; done;
和Xreset文件的代码:
-- snip -- for script in /etc/session.d/kdm/reset/*.sh; do if [ -x $script ]; then eval $script $USER kdm fi; done;
创建脚本所在的目录:
install -m755 -d /etc/session.d/kdm/startup
install -m755 -d /etc/session.d/kdm/reset
install -m755 -d /etc/session.d/scripts/start
install -m755 -d /etc/session.d/scripts/stop
这些目录中的文件必须能够为每个普通用户访问:因此权限为755。
这些目录中的所有脚本应具有相同的权限:755。
每个用户都应该能够执行脚本,但只有root才能修改它们。
1.启动dbus的sessiondaemon并使环境变量可用
dbus包分为两部分:一个系统范围部分,一个用于(每个)会话/用户。 系统范围部分(守护进程)在引导时启动,具有专用用户的特殊权限。 会话范围部分(也是守护进程)必须在用户会话开始时启动,会话结束时停止。
我在这里使用kdm的建设是理想的。 启动目录中的一个脚本为用户启动sessiondaemon,以该用户的权限运行,另一个在reset目录中,另一个脚本必须停止该守护程序。
但不是那么简单。 一些变量(DBUS_SESSION_BUS_ADDRESS和DBUS_SESSION_BUS_PID)必须在环境中可用于适用于dbus的每个应用程序。 这些变量的设置应该在bash-startupscripts中。 然后,无论您运行的脚本或应用程序,这些变量都设置为正确的值。
1.1关于Bash的启动文件
dbus的sessiondaemon创建一个包含环境变量的文件。 如上所述,当该文件启动时,该文件应该被bash读取(源代码)。
当通过“登录”启动bash作为交互式登录shell时,它会读取/ etc / profile和〜/ .bash_profile。 Bash也由“kdm”启动,文件/ etc / profile和〜/ .bash_profile来源。
我的想法是存储命令的输出
dbus-launch --auto-syntax
在文件中
$ HOME / .dbus-session
当bash启动时,此文件为“源”。 这不会自动发生,但您必须将以下脚本添加到/etc/profile.d:
cat >> /etc/profile.d/dbus-session.sh << "EOF" if [ -f $HOME/.dbus-session ]; then . $HOME/.dbus-session fi; EOF
这样,当Bash启动时,环境变量就可以使用了。
1.2启动dbus的sessionbus部分
我假设dbus是安装的,并且它在启动时启动。
在/etc/session.d/scripts/start目录下创建一个脚本dbus-session-start.sh:
cd /etc/session.d/scripts/start
cat >> dbus-session-start.sh << "EOF" #!/bin/bash retcode=0; userid=$1 userproperties=$(getent passwd | grep -m 1 -E "^$userid") homedir=$(echo $userproperties | cut -d ":" -f 6); gidnr=$(echo $userproperties | cut -d ":" -f 4); uidnr=$(echo $userproperties | cut -d ":" -f 3); if [ -d $homedir ]; then # # do a check whether dbus-daemon is already running # dbus-daemon needs to be started by the user (uidnr) logging in # if [ -f $homedir/.dbus-session ]; then # do a check the dbus-daemon for this user is running with the pid # in the .dbus-session file # pid according to the ps command ps_dbus_session_pid=$(ps aux | grep -m 1 -E "^$userid.*dbus-daemon.*session.*" \ | grep -v "grep" | sed 's@[[:space:]][[:space:]]*@ @g' | cut -d " " -f 2) # read the pid from the .dbus-session file . $homedir/.dbus-session # check they are the same if [ -z "$ps_dbus_session_pid" ]; then # dbus for this user not running rm $homedir/.dbus-session elif [ $DBUS_SESSION_BUS_PID -ne $ps_dbus_session_pid ]; then # there is something wrong: stop dbus-daemon for this user # and remove .dbus-session file if [ $(id -u) -eq 0 ]; then sudo -H -u $userid sh -c "kill $ps_dbus_session_pid" elif [ $(id -u) -eq $uidnr ]; then kill -SIGTERM $ps_dbus_session_pid; fi rm $homedir/.dbus-session fi fi if [ ! -f $homedir/.dbus-session ]; then # only start a dbus session if .dbus-session file it not found # in users homedirectory if [ $(id -u) -eq 0 ]; then sudo -u $userid -H /bin/sh -c "dbus-launch --auto-syntax > $homedir/.dbus-session" retcode=$? chown $uidnr:$gidnr $homedir/.dbus-session elif [ $(id -u) -eq $uidnr ]; then dbus-launch --auto-syntax > $homedir/.dbus-session retcode=$? fi fi fi; if [ $retcode -ne 0 ]; then echo "An error with dbus ($retcode)." fi; exit $retcode EOF
chmod --verbose --mode 755 /etc/session.d/scripts/start/dbus-session-start.sh
ln -v -sf ../../scripts/start/dbus-session-start.sh /etc/session.d/kdm/startup/10dbus.sh
由KDM在启动时执行的此脚本将启动该用户的dbus会话守护进程,并将在该用户的目标中创建包含所有dbusvariables的.dbus会话文件。
当dbus尚未为此用户运行时,它才会执行此操作。
现在当bash在登录时开始,它读取(源)这个文件。
正如你所看到的,我把dbus的开始分成两部分:
- dbus-session-start.sh,在(kdm)会话开始时运行
- .dbus会话,当(bash)会话启动时,可以多次采集
此外,我使用--auto-syntax参数,我假设使用了Bash。 所以我可以在这里使用--sh语法,但它有效。
而Sudo需要作为登录用户运行dbus-launcher,因为KDM以root身份运行此脚本。 (实际上脚本检查运行此脚本的帐号的id,它是root(id = 0),然后sudo用于更改用户启动会话,当登录的用户的id和id相同时没有什么必须做的。
2.3停止dbus的sessionbus部分
在reset目录中创建dbus-session-stop.sh脚本:
cd /etc/session.d/scripts/stop
cat >> dbus-session-stop.sh << "EOF" #!/bin/bash retcode=0; userid=$1 userproperties=$(getent passwd | grep -m 1 -E "^$userid") homedir=$(echo $userproperties | cut -d ":" -f 6); gidnr=$(echo $userproperties | cut -d ":" -f 4); uidnr=$(echo $userproperties | cut -d ":" -f 3); if [ -f $homedir/.dbus-session ]; then . $homedir/.dbus-session if [ -n "$DBUS_SESSION_BUS_PID" ]; then if [ $(id -u) -eq 0 ]; then sudo -u $userid -H /bin/sh -c "kill $DBUS_SESSION_BUS_PID" retcode=$? rm $homedir/.dbus-session elif [ $(id -u) -eq $uidnr ]; then kill $DBUS_SESSION_BUS_PID retcode=$? rm $homedir/.dbus-session fi fi fi; if [ $retcode -ne 0 ]; then echo "An error with dbus ($retcode)." fi; exit $retcode EOF
chmod --verbose --mode 755 dbus-session-stop.sh
ln -v -sf ../../scripts/stop/dbus-session-stop.sh /etc/session.d/kdm/reset/90dbus.sh
此脚本停止dbus-daemon的会话部分。
2.4一个用户登录不止一次
对于大多数情况,这种建设是足够好的。 大多数用户一次有一个会话。 现在,当用户同时拥有多个会话时会发生什么? 每个会话启动dbus的会话是否可以,还是一个实例?
这种结构不允许每个用户多于一个dbus-daemon。 我觉得应该够好了
更改:
[2006-01-18]
*初始化方式
[2006-07-18]
*更改了bash脚本
[2006-09-09]
*添加检查以查看dbus-daemon是否已经为此用户运行,并且.dbus-session中的信息是正确的