dbusとKDE · 2 min read · Jan 03, 2026

dbusとKDEの統合:KDMでのセッション部分の開始と停止

dbusとKDEの統合:KDMでのセッション部分の開始と停止

目次

  1. はじめに
  2. KDMの設定の調整
  3. dbusのセッションデーモンを開始し、環境変数を利用可能にする。
    2.1 Bashのスタートアップファイルについて。
    2.2 dbusのセッションバス部分を開始
    2.3 dbusのセッションバス部分を停止
    2.4 一人のユーザーが複数回ログインしている

0. はじめに

ここ最近、多くのアプリケーションがD-BUSを利用しています。これはKDE 3.5、現在のKDEの安定版リリースに当てはまります。今後のKDE 4では、D-BUSがより重要になり、DCOPに取って代わります。

このハウツーでは、ユーザーおよびセッション依存のdbus部分を開始および停止する方法を説明します。このアプローチで私が考えている主な目標は次のとおりです:

  • d-busを意識したアプリケーションに重要な環境変数を利用可能にする;
  • 単一のユーザーに対してdbusセッション部分が一度以上開始されないようにする;
  • ユーザーのセッションが終了したときにdbusセッション部分が停止されることを確認する;

ユーザーがKDM(KDE 3.5用のログインマネージャ)でログインすると仮定します。この構成は他のログインマネージャ(XDM、GDM)でも使用できます。
KDMには、セッションの開始時(起動時)および終了時(リセット時)にスクリプトを実行する機能があります。そのうちの1つがdbusセッション部分を開始(および停止)できます。

1. KDM:ファイル

KDMは開始と停止のためにいくつかのファイルを使用します:

. Xstartup
ユーザーが正常にログインした後、rootとして実行されます。

. 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のセッションデーモンを開始し、環境変数を利用可能にする

dbusパッケージは2つの部分に分かれています:1つはシステム全体の部分、もう1つは(各)セッション/ユーザーのための部分です。システム全体の部分(デーモン)はブート時に特権を持つ専用ユーザーによって開始されます。セッション全体の部分(これもデーモン)は、ユーザーのセッションが始まるときに開始され、セッションが終了するときに停止される必要があります。

ここで使用しているkdmの構成はこれに理想的です。ユーザーのためにセッションデーモンを開始するためのスクリプトがスタートアップディレクトリにあり、そのユーザーの権限で実行され、リセットディレクトリにある別のスクリプトがそのデーモンを停止する必要があります。

しかし、それはそれほど簡単ではありません。いくつかの変数(DBUS_SESSION_BUS_ADDRESSおよびDBUS_SESSION_BUS_PID)は、dbusで動作するすべてのアプリケーションに対して環境内で利用可能である必要があります。私の意見では、これらの変数の設定はbashスタートアップスクリプトに含めるべきです。そうすれば、実行しているスクリプトやアプリケーションに関係なく、これらの変数は正しい値に設定されます。

1.1 Bashのスタートアップファイルについて

dbusのセッションデーモンは、環境変数を含むファイルを作成します。上記のように、このファイルはbashがこのユーザーのために起動するときに読み込まれる(ソースされる)必要があります。

bashが「login」によってインタラクティブログインシェルとして起動されると、/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のセッションバス部分を開始

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
    #
    # dbus-daemonがすでに実行中かどうかを確認
    # dbus-daemonはユーザー(uidnr)がログインすることで開始される必要があります
    #
    
    if [ -f $homedir/.dbus-session ]; then
        # このユーザーのdbus-daemonが.pidファイルで実行中かどうかを確認
        # .dbus-sessionファイルのpid
 
        # psコマンドによるpid
        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)
        
        # .dbus-sessionファイルからpidを読み込む
        . $homedir/.dbus-session
        # 同じかどうかを確認
        if [ -z "$ps_dbus_session_pid" ]; then
            # このユーザーのdbusは実行されていない
            rm $homedir/.dbus-session
            
        elif [ $DBUS_SESSION_BUS_PID -ne $ps_dbus_session_pid ]; then
            # 何かが間違っている:このユーザーのdbus-daemonを停止し、.dbus-sessionファイルを削除
            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
        # .dbus-sessionファイルが見つからない場合のみdbusセッションを開始
        # ユーザーのホームディレクトリに
        
        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 "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-sessionファイルを作成し、すべてのdbus変数を含みます。
これは、dbusがすでにこのユーザーのために実行されていない場合にのみ行われます。

これで、ログイン時にbashが起動すると、このファイルが読み込まれます(ソースされます)。

ご覧のとおり、dbusの開始を2つの部分に分けました:

  • dbus-session-start.shは(kdm)セッションが開始されるときに実行されます
  • .dbus-sessionは(bash)セッションが開始されるときにソースされ、複数回ソースされる可能性があります

さらに、–auto-syntaxパラメータを使用しています。ここではBashが使用されていると仮定しています。したがって、ここで–sh-syntaxを使用することもできますが、動作します。

KDMがこのスクリプトをrootとして実行するため、dbus-launcherをログインしているユーザーとして実行するにはsudoが必要です。(実際、このスクリプトを実行しているアカウントのidを確認します。root(id = 0)であれば、sudoを使用してセッションを開始するユーザーに切り替えます。idとログインしているユーザーのidが同じであれば、何もする必要はありません。

2.3 dbusのセッションバス部分を停止

リセットディレクトリに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 "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 一人のユーザーが複数回ログインしている

ほとんどの状況では、この構成で十分です。ほとんどのユーザーは同時に1つのセッションを持っています。では、ユーザーが同時に複数のセッションを持っている場合はどうなりますか?各セッションのためにdbusのセッション部分を開始する必要がありますか、それとも1つのインスタンスで十分ですか?

この構成では、ユーザーごとに1つのdbus-daemonしか許可されていません。これで十分だと思います。

変更履歴:

[2006-01-18]

  • 初回ハウツー
    [2006-07-18]
  • bashスクリプトを変更
    [2006-09-09]
  • このユーザーのためにdbus-daemonがすでに実行中かどうかを確認し、.dbus-sessionに見つかった情報が正しいかどうかを確認するチェックを追加
Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。