24

状況:複数のモニターを使用していて、それらの名前をbashで取得したい。現在、Ubuntu10.04を使用しています。

xrandrについて知っています。それから私は統計データしか得ることができません。私が欲しいのは、それらを操作するために配列内のすべてのモニター名を読み取ることです。

ある種の文字列から名前を切り取らずにそれを行う明確な方法はありますか?明確な方法は、ファイルからそれらを読み取ることです。明確ではない方法は、xrandr出力をある種の関数にパイプして、そこから名前を切り出すことです。

4

7 に答える 7

27

ベニの答えに触発されて、これはEDID仕様に従ってモニター名を使用してEDIDデータを読み取り、抽出します。次のような外部ツールは必要ありません。xrandrparse-edid

#!/bin/bash
while read -r output hex conn; do
    [[ -z "$conn" ]] && conn=${output%%-*}
    echo "# $output $conn   $(xxd -r -p <<< "$hex")"
done < <(xrandr --prop | awk '
    !/^[ \t]/ {
        if (output && hex) print output, hex, conn
        output=$1
        hex=""
    }
    /ConnectorType:/ {conn=$2}
    /[:.]/ && h {
        sub(/.*000000fc00/, "", hex)
        hex = substr(hex, 0, 26) "0a"
        sub(/0a.*/, "", hex)
        h=0
    }
    h {sub(/[ \t]+/, ""); hex = hex $0}
    /EDID.*:/ {h=1}
    END {if (output && hex) print output, hex, conn}
    ' | sort
)

awkモニター名のみを正確に抽出するために使用し、EDIDから余分なゴミを抽出しないため、、、などの「マジックナンバー」000000fc00を使用260aます。最後に、を使用xxdして16進数からASCIIに変換し、1行に1つのモニター名を出力します。

このソリューションに基づいて、モニターを切り替えるための便利なスクリプトを作成しました。これは、モニター情報をリストするためにも使用できます。

$ monitor-switch --list
Connected monitors:
# DFP5  HDMI    HT-R391
# DFP7  DVI-I   DELL U2412M

$ monitor-switch --list
Connected monitors:
# DisplayPort-1 DisplayPort DELL U2412M
# DisplayPort-3 DisplayPort DELL U2415
# HDMI-A-2      HDMI        LG TV
于 2014-07-24T12:11:56.837 に答える
18

Ubuntu 16.04、18.04でテスト済み。(私は答えるには遅すぎることを知っていますが、この解決策は今日関連しています)

$ sudo apt-get install -y hwinfo
...
$ hwinfo --monitor --short
monitor:
                   SONY TV
                   AUO LCD Monitor

2台のモニターを取り付けています。1つはラップトップを搭載し、もう1つは外部ディスプレイです。外部モニターがプラグインまたはプラグアウトされるとすぐに、このコマンドは変更を反映します。継続的にポーリングする必要があります。オプションを削除すると、--shortより詳細な情報が得られます。

次のバックグラウンドジョブを使用して状態をポーリングできます。

$ while true;
>  do
>   hwinfo --monitor --short;
>   sleep 2;
>  done >> monitor.log &

while trueループは無限に実行されます。ループのsleep 2各反復を2秒間一時停止します。そして、の出力hwinfo --monitor --shortはに追加されmonitor.logます。このログファイルは、モニタープラグインとプラグアウトのアクティビティ履歴を提供します。

参考:私は、上記のコマンド(および他の同様のコマンド)を使用してバックグラウンド(デーモン)pythonスクリプトを使用して、誰かがコンピューターラボのシステムでHWプラグインおよびプラグインを実行しているかどうかを検出しています。もしそうなら、誰かがほぼリアルタイムでモニター、マウス、またはキーボードをプラグアウト/プラグインしたという適切な通知を受け取ります!

hwinfoコマンドの詳細については、こちらをご覧ください。そのマニュアルページも良い情報源です。

于 2017-05-11T16:17:51.227 に答える
10

sudo get-edid私のために働いていませんでした。(編集:別のコンピューター、Lubuntu 14.10で動作するようになりました。BIOSの違いを非難しますが、それはランダムな推測です...)

とにかくXの下でxrandr --verbose、EDIDブロックを印刷します。これは、それを抽出してに渡すための迅速で汚い方法parse-edidです:

#!/bin/bash
xrandr --verbose | perl -ne '
if ((/EDID(_DATA)?:/.../:/) && !/:/) {
  s/^\s+//;
  chomp;
  $hex .= $_;
} elsif ($hex) {
  # Use "|strings" if you dont have read-edid package installed 
  # and just want to see (or grep) the human-readable parts.
  open FH, "|parse-edid"; 
  print FH pack("H*", $hex); 
  $hex = "";
}'
于 2013-08-15T02:39:12.200 に答える
2

出力を解析したくない場合は、必要なものだけを取得xrandrするCプログラムを作成してください。libXrandr情報を照会するだけであれば、すばやく実行できます。このドキュメントを読んでください

実際のモニター名を取得する場合、@ dtmilanoのソリューションの代わりに、libXrandrを使用してモニターのEDIDプロパティを取得し、手動で解析して印刷することもできます(EDID仕様を参照)。

xrandrソースコード

于 2012-05-09T12:29:36.260 に答える
2

私はこれが汚い方法であることを知っています、しかしそれは私にいくつかのモニターモデル名をより良く与えますsudo get-edid|parse-edid。配列内の情報を読み取り、ファイルを読み取るのと同じように読み取ることができる方法で出力します。必要に応じて変更できます。

#!/bin/bash
#
#
#    get-monitors.sh
#
#    Get monitor name and some other properties of connected monitors
#    by investigating the output of xrandr command and EDID data
#    provided by it.
#
#    Copyright (C) 2015,2016 Jarno Suni <8@iki.fi>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program. See <http://www.gnu.org/licenses/gpl.html>

set -o nounset
set -o errexit

# EDID format:
# http://en.wikipedia.org/wiki/Extended_Display_Identification_Data#EDID_1.3_data_format
# http://read.pudn.com/downloads110/ebook/456020/E-EDID%20Standard.pdf

declare -r us=';' # separator string;
# If EDID has more than one field with same tag, concatenate them,
# but add this string in between.

declare -r fs=$'\x1f' # Field separator for internal use;
# must be a character that does not occur in data fields.

declare -r invalid_edid_tag='--bad EDID--'
# If base EDID is invalid, don't try to extract information from it,
# but assign this string to the fields.

# Get information in these arrays:
declare -a outs  # Output names
declare -a conns # Connection type names (if available)
declare -a names # Monitor names (but empty for some laptop displays)
declare -a datas # Extra data; may include laptop display brand name
                 # and model name
declare -i no    # number of connected outputs (to be counted)

# xrandr command to use as a source of information:
declare -r xrandr_output_cmd="xrandr --prop"

hex_to_ascii() {
    echo -n "$1" | xxd -r -p
}

ascii_to_hex() {
    echo -n "$1" | xxd -p
}

get_info() {
    no=0
    declare OIFS=$IFS;
    IFS=$fs
    while read -r output conn hexn hexd; do
        outs[no]="${output}"
        conns[no]="${conn}"
        names[no]="$(hex_to_ascii "$hexn")"
        datas[no]="$(hex_to_ascii "$hexd")"
        (( ++no ))
    done < <(eval $xrandr_output_cmd | gawk -v gfs="$fs" '
        function print_fields() {
            print output, conn, hexn, hexd
            conn=""; hexn=""; hexd=""
        }
        function append_hex_field(src_hex,position,app_hex,  n) {
                     n=substr(src_hex,position+10,26)
                     sub(/0a.*/, "", n)
                     # EDID specification says field ends by 0x0a
                     # (\n), if it is shorter than 13 bytes.
                     #sub(/(20)+$/, "", n)
                     # strip whitespace at the end of ascii string
                     if (n && app_hex) return app_hex sp n
                      else return app_hex n
        }
        function get_hex_edid(  hex) {
            getline
            while (/^[ \t]*[[:xdigit:]]+$/) {
                sub(/[ \t]*/, "")
                hex = hex $0
                getline
            }
            return hex
        }
        function valid_edid(hex,  a, sum) {
            if (length(hex)<256) return 0
            for ( a=1; a<=256; a+=2 ) {
                # this requires gawk
                sum+=strtonum("0x" substr(hex,a,2))

                # this requires --non-decimal-data for gawk:
                #sum+=sprintf("%d", "0x" substr(hex,a,2))
            }
            if (sum % 256) return 0
            return 1
        }
        BEGIN {
            OFS=gfs
        }
        /[^[:blank:]]+ connected/ {
            if (unprinted) print_fields()
            unprinted=1
            output=$1
        }
        /[^[:blank:]]+ disconnected/ {
            if (unprinted) print_fields()
            unprinted=0
        }
        /^[[:blank:]]*EDID.*:/ {
            hex=get_hex_edid()
            if (valid_edid(hex)) {
                for ( c=109; c<=217; c+=36 ) {
                    switch (substr(hex,c,10)) {
                        case "000000fc00" :
                         hexn=append_hex_field(hex,c,hexn)
                         break
                        case "000000fe00" :
                         hexd=append_hex_field(hex,c,hexd)
                         break
                    }
                }
            } else {
              # set special value to denote invalid EDID
              hexn=iet; hexd=iet
            }
        }
        /ConnectorType:/ {
            conn=$2
        }
        END {
            if (unprinted) print_fields()
        }' sp=$(ascii_to_hex $us) iet=$(ascii_to_hex $invalid_edid_tag))

    IFS="$OIFS"
}

get_info

# print the colums of each display quoted in one row
for (( i=0; i<$no; i++ )); do
    echo "'${outs[i]}' '${conns[i]}' '${names[i]}' '${datas[i]}'"
done
于 2015-04-06T23:20:07.380 に答える
1

試してみddcprobeてくださいget-edid

$ sudo apt-get install xresprobe read-edid
$ sudo ddcprobe
$ sudo get-edid
于 2012-05-08T18:15:48.490 に答える
0

I²Cバスに沿って渡され、ビデオドライバーによって解釈されるEDID情報を探しています。dtmilanoが言うように、ddcprobeからのget-editは機能するはずです。

Xの開始をログに記録することによって、この情報を取得することもできます。

startx -- -logverbose 6

数年前、私はread-edidというパッケージを使用してこの情報を収集しました。

2009年のこのブログ投稿によると、read-edidパッケージはすでにUbuntuで利用可能である可能性があります。

于 2012-05-09T12:37:26.730 に答える