bashスクリプト(.bashrcなど)でXセッションを検出する


16

最近xset b off、.bashrc に置きました。今、私はttyまたはssh経由、つまりXセッション外でログインするとthetがポップアップするエラーに悩まされています。

私が最初に思いついたのは、[[ -z "$SOME_VAR" ]] && xset b off変数の設定と空のテストは別の質問であることが判明したことです)。しかし、どのSOME_VARが正しいのでしょうか?

そこで、ttyのset出力とurxvtのset出力を比較して、どの変数がXに設定されており、ttyにないかを確認しました。予想どおり、非常に多くの違いがありました(自分に関連があると思われるもののみをリストします)。

  • DESKTOP_SESSION
  • DISPLAY
  • GDMSESSION
  • SESSION_MANAGER
  • WINDOWID
  • WINDOWPATH
  • XAUTHORITY
  • XDG_SESSION_COOKIE
  • XDG_CONFIG_DIRS
  • XDG_DATA_DIRS
  • XDG_MENU_PREFIX

Xセッションに参加しているかどうかを検出するためにテストするのに最も適切で普遍的なものはどれですか?できるだけ多くのディストリビューション、プラットフォーム、デスクトップ環境で機能するものはありますか?

または、環境変数をテストするよりも良い方法はありますか?

回答:


8

ディスプレイサーバーが利用可能で有効であることをテストする簡単で効果的な方法は、を使用してテストすることxhostです。DISPLAY無効な値が設定されている可能性があるため、変数の値のチェックに常に依存することはできません。

if xhost >& /dev/null ; then echo "Display exists"
else echo "Display invalid" ; fi

私がこれを行う理由はcrontab、ディスプレイが存在する場合はディスプレイ上で動作するが、存在しない場合は動作が異なる複数のスクリプトをユーザーで実行するためです。の一番上で、まだ存在していなくても変数crontabを設定しDISPLAYます:0crontabで始まるスクリプト@rebootは、ディスプレイがあるかどうかに関係なく開始されます。これにより、同じスクリプト内でディスプレイがいつ出入りするかを動的に検出できます。

注:> = 4 >&でのみ機能しbashます。> /dev/null 2>&1


ニース、またテスト済みssh -X。正常に動作します!
アロイスマーダル

13

チェックDISPLAYが最善のアプローチだと思います。

  • リモートログインを処理します(ssh -Xなど)。
  • すべてではありませんが、ほとんどのプラットフォームで利用可能です。
  • ウィンドウマネージャー/ DEから独立しています。

2
またDISPLAY、を選択するか、一般的なエラーメッセージを単に抑制します。/dev/null時々愛を与えてください。
frostschutz

3
@frostschutzいいえ、スクリプトの関連部分のみを実行しようとしています。エラーメッセージを非表示にしても、その方向に進むことはありません。実際、潜在的に破損する可能性のある他の問題のトラブルシューティングを行う場合、深刻な混乱を招く可能性があります。
アロイスマーダル

1
私は答えのすぐ後にこのアプローチを使用し始めました、そしてそれsshが私がやるようになった今までシンプルなsで完全に機能しましたssh -X-ビジュアルモードで選択されたコンテンツがローカルXクリップボードに到達するようにVimをssh経由で使用できるようにサーバー側にxserverは必要ありません。したがって、DISPLAYは、xserverおよびxsetが存在しない場合でも、単に転送を有効にするだけの効果として設定されます。
アロイスマーダル

それは次のようになりますif [[ $DISPLAY ]]; then … fi
セルジュStroobandt

1
あなたのDISPLAY変数は、(それがスクリプトにハードコードされた、または変数が設定された後にXサーバーがシャットダウンされたときなど)、実際にXサーバで実行していないディスプレイを指すことができます。
n.st

6

私は通常使用します TERM、スクリプトでXをテストするために変数をます。

TERM通常に設定されているlinuxTTY上やxtermX上で
GNU画面とTMUXなどのアプリケーションが混乱しているように見えるので、私は、ここでは「通常」という言葉を使うTERM変数。


試すecho $TERM異なるコンソールであなたのmashineにricht設定を見つけるために。[ $TERM == "linux" ] && echo do some stuffUbuntuで使用しています
-rubo77

3

これは完全にうまくいくはずです:

[ ! -t 0 ] && xset b off                                  

http://tldp.org/LDP/abs/html/fto.html

-t

    file (descriptor) is associated with a terminal device

    This test option may be used to check whether the stdin [ -t 0 ] 
    or stdout [ -t 1 ] in a given script is a terminal.

したがって、これがfalse([ ! -t 0 ])と評価されると、GUI環境になります。


これで、私はつまり、両方のXで、コンソールで同じ結果を得る[ -t 0 ][ -t 1 ]、両方の真です。
エマニュエルベルク

奇妙なことに、リモートホストに接続するときに機能します。
テルドン

[ -t 0 ]Ubuntuのコンソールで正常に動作します(CTRL ALT F1を使用)
rubo77

0

それを行うには多くの方法があります。

bashでは、試してください

function xruns {
    if [[ `pstree -As $$ | grep xinit | wc -l` == 1 ]]; then
        echo "You are in X."
    else
        echo "You are not in X."
    fi
}

または、zshで試してください

#!/usr/bin/zsh

CURRENT_VT=`tty`

if [[ ${CURRENT_VT[6]} == "p" ]];        # or `${CURRENT_VT:5:1}` in bash
then
   # X stuff
else 
   # non-X stuff      
fi

重要な点ですが、投稿する前にコードをテストしますか?最初のスクリプトには構文エラーがあり、Xセッションecho 1が実行されているかどうか実際には検出されません。もう1つは常に「X以外の処理」を行います。これ${CURRENT_VT[6]}は、6番目の文字ではなく6番目の行を意味すると思います。
アロイスマーダル

@AloisMahdal:ああ、私のものはbashでは動作しません(zshを使用しています)。それを考えなかった。まあ、zsh(タイプzsh)で試してみて、必要に応じてbashで動作するようにいくつかの変更を加えることもできます。
エマニュエルベルク

@AloisMahdal:OK、変更しました。「tty1-6経由のログイン」に関しては、それが私がしていることであり、それから2番目のソリューション(上記)を使用して変数を設定します。これ .zshrcをチェックしを検索してくださいexport VT。この変数を使用して、Linux VT / console / tty(zshプロンプトの場合)を保持しますが、Xでは「X」に設定します(VTではありません)。しかし、それは詳細です。同じ原則を使用して、bashで任意の方法で解決できます。
エマニュエルベルク

2番目の例に条件のbashバージョンを追加しました。しかし、最初のものはまだ間違っていると思います。おそらく先祖だけをpsで印刷すると役立つでしょう。しかし、それが可能かどうかはわかりません。
アロイスマーダル

@AloisMahdal:編集をご覧ください。ttyのものを含め、それは私のためにそれを行います。
エマニュエルベルク

0

if [[ $DISPLAY ]]

同じコンピューター上で、$DISPLAYたとえば0:0ターミナルエミュレーターでは戻りますが、実際のターミナルでは戻りません。これはCtrlAltF1vsで簡単にテストできますCtrlAltF7

A bash基づく条件$DISPLAYは次のようになります。

if [[ $DISPLAY ]]; then 
  
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.