web-dev-qa-db-ja.com

特定のttyの表示番号を取得します

XがDebianマシンの特定のTTYで実行されているかどうかを確認し、その場合は表示番号(DISPLAYの値)を取得するにはどうすればよいですか?

編集:TTYは非アクティブなコンソールである可能性があり、必ずしもアクティブなコンソールである必要はありません。関数を実装しようとしています

Display()
{
    local tty="$1"
    ...
}
3

プロセス名で検索できます。次に、プロセスによって開かれているUNIXドメインソケット(おそらく抽象)を調べて、表示番号を決定します。

pid=$(pgrep -xt "$tty" Xorg) &&
  lsof -aUp "$pid" | sed '\|.*X11-unix/X\([0-9]\{1,\}\) .*|!d;s//\1/;q'

そのlsofはrootとして実行する必要があります。

または、表示番号が常に存在する場合は、コマンドライン引数から表示番号を抽出できます。

pgrep -axt "$tty" Xorg | sed -n 's/.*:\([0-9]\{1,\}\).*/\1/p'
5

/dev/ttyNNから$DISPLAYへのマッピングを解決する簡単な方法がわかりません。ただし、それは可能です。私のDebianベースのシステムでは、これは:0で実行されているXセッションのローカルDISPLAY/dev/tty7を返します。

xtty=/dev/tty7
xpid=$(lsof "$xtty" 2>/dev/null | awk '$1 == "Xorg" {print $2}')
test -n "$xpid" && ps -fp "$xpid" | awk '$2 == xpid {print $9}' xpid="$xpid"    # → :0

中間段階は以下のとおりです。

  1. lsofは、指定されたtty端末で開いているすべてのプロセスを返します。 awkは、Xorgという名前のプロセスのプロセスIDを選択します。その特定のXディスプレイサーバーを実行していない場合はYMMV。

    lsof /dev/tty7 2>/dev/null
    COMMAND PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
    Xorg    695 root    8u   CHR    4,7      0t0 1059 /dev/tty7
    
  2. ps | awkの組み合わせは、一致したXorgプロセスの十分な詳細を提供して、DISPLAY名を配信します。

    ps -fp 695
    UID        PID  PPID  C STIME TTY          TIME CMD
    root       695   639  0 Jan23 tty7     00:01:44 /usr/bin/X :0 -seat seat0 -auth /var/run/lightdm
    
4
roaima

LinuxマシンとGNUツールを想定すると、これは機能するはずです:

#!/bin/bash

## Get Xorg's tty
xorgTTY="$(ps -o tty= "$(pgrep Xorg)")"
## Get the DISPLAY from a process running on that tty
while read pid; do
    display="$(grep -aoP 'DISPLAY=\K[^\0]+' /proc/"$pid"/environ)" && break
done < <(pgrep -t "$xorgTTY")
echo "$display"
4
terdon

bashがシェルであると仮定すると、このようなものが機能する可能性があります。

TTY="pts/20"
BASH_PID="$(ps -t $TTY|awk '$4 == "bash" {print $1;exit}')"
TTY_DISPLAY=$(tr '\000' '\n' < /proc/$BASH_PID/environ|awk -F'=' '$1 == "DISPLAY" {print $2}')

TTYを指定し、最初に見つかったbash pidを取得してから、/proc/pid/environからDISPLAYvarを抽出します。

2
Zachary Brady

Systemd-logind(Debian 8を含む必要があります)を使用するマシンでは、次のようにlogindを照会できます。

DisplayName()
{
  local ttynr="$1"
  declare -A property
  for session in $(loginctl --no-legend list-sessions | awk '{ print $1 }' ); do
    while IFS="=" read key value ; do
      property[$key]="$value"
    done < <(loginctl show-session $session)

    if [ "${property[VTNr]}" = "$ttynr" ] && [ -n "${property[Display]}" ]; then
      echo "${property[Display]}"
      return 0
    fi
  done
  return 1
}
1
hobbs

私のDebian8システムでは、すべてのXプロセスが仮想端末を受け取ります(例:vt1)と表示名(例::0)引数として。ただし、Xセッションがディスプレイマネージャによって開始されたか、コンソールから開始されたかによって、引数の位置は異なります。 roaimaの答えに触発されて、私は次のシェル関数を作成しました。

DisplayName()
{
    local ttyNr="$1"

    ps -ef | awk -v ttyNr="$ttyNr" \
        '$8 == "/usr/bin/X" {
            for (i = 9; i <= NF; i++) {
                if ($i == "vt" ttyNr) {
                    isMatch = 1
                } else if ($i ~ "^:[0-9]+$") {
                    display = $i
                }
            }
            if (isMatch) {
                print display
                exit
            }
        }'
}
0

さて、最短の答えは一文字かもしれないと思います:

$ w

USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
arnie97  tty1     -                21:50    2:11   9.94s  8.88s -bash
arnie97  tty7     :0               20:56    1:09m 45.68s  0.02s /bin/sh /etc/xdg/xfce4/xinitrc -- /etc/X11/xinit/xserverrc
arnie97  pts/0    192.168.0.1      22:31    0.00s  0.44s  0.30s vi

スクリプトに関して:

$ w -h | awk '$3 ~ /^:/ { if ($2 == "tty7") print $3 }'

:0
0
Arnie97