Linux检索监视器名称

Linux检索监视器名称,linux,ubuntu,xserver,Linux,Ubuntu,Xserver,情境:我使用多个监视器,我想在bash中获取它们的名称。目前我正在使用Ubuntu 10.04 我知道xrandr。从中我只能得到统计数据。我想要的是读取数组中的所有监视器名称以使用它们 有没有一种明确的方法可以做到这一点,而不必从某种字符串中删除名称?一个明确的方法是从文件中读取它们。一个不明确的方法是将xrandr输出通过管道传输到某种类型的函数以从中删除名称。您可以尝试ddcprobe和/或获取edid $ sudo apt-get install xresprobe read-edid

情境:我使用多个监视器,我想在bash中获取它们的名称。目前我正在使用Ubuntu 10.04

我知道xrandr。从中我只能得到统计数据。我想要的是读取数组中的所有监视器名称以使用它们


有没有一种明确的方法可以做到这一点,而不必从某种字符串中删除名称?一个明确的方法是从文件中读取它们。一个不明确的方法是将xrandr输出通过管道传输到某种类型的函数以从中删除名称。

您可以尝试
ddcprobe
和/或
获取edid

$ sudo apt-get install xresprobe read-edid
$ sudo ddcprobe
$ sudo get-edid

如果您不想解析
xrandr
输出,请使用
libXrandr
编写一个只获取所需内容的C程序。如果您只想查询信息,那么可以快速完成

如果您想获得真实的监视器名称,@dtmilano解决方案的另一个替代方案是使用libXrandr获取监视器的EDID属性,然后手动解析并打印(阅读EDID规范)

.

您正在查找信息,这些信息通过I²C总线传递,并由视频驱动程序进行解释。正如dtmilano所说,从ddcprobe获取编辑应该是可行的

您还可以通过记录X开始来获取此信息:

startx -- -logverbose 6
几年前,我使用了一个名为的包来收集这些信息


从2009年开始,read edid软件包可能已经在Ubuntu中提供了。

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 = "";
}'
#!/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
)

受Beni回答的启发,这将使用
xrandr
读取数据,并根据提取监视器名称,而不需要任何外部工具,如
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 = "";
}'
#!/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
)

我知道这是一种肮脏的方式,但它给了我一些监视器模型名称,甚至比
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
#/bin/bash
#
#
#get-monitors.sh
#
#获取已连接监视器的监视器名称和其他一些属性
#通过调查xrandr命令和EDID数据的输出
#由它提供。
#
#版权所有(C)20152016 Jarno Suni
#
#此程序是免费软件:您可以重新发布和/或修改它
#它是根据GNU通用公共许可证的条款发布的
自由软件基金会,或者许可证的第3版,或者
#(由您选择)任何更高版本。
#
#这个节目的发布是希望它会有用,
#但无任何保证;甚至没有任何关于
#适销性或适合某一特定目的。见
#有关更多详细信息,请参阅GNU通用公共许可证。
#
#您应该已经收到GNU通用公共许可证的副本
#和这个节目一起。看见
集合-o名词集合
set-o errexit
#EDID格式:
# 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
声明-r us=';'#分离器串;
#如果EDID有多个具有相同标记的字段,请将它们连接起来,
#但是在两者之间加上这个字符串。
声明-r fs=$'\x1f'#内部使用的字段分隔符;
#必须是数据字段中不出现的字符。
声明-r无效\u edid\u标记='--错误的edid--'
#如果基本EDID无效,请不要尝试从中提取信息,
#但将此字符串指定给字段。
#获取以下阵列中的信息:
声明-a输出#输出名称
声明-a连接#连接类型名称(如果可用)
declare-a names#监视器名称(但对于某些笔记本电脑显示器为空)
声明-一个数据#额外数据;可能包括笔记本电脑显示品牌名称
#和型号名称
声明-i无#连接输出的数量(待统计)
#要用作信息源的xrandr命令:
声明-r xrandr\u输出\u cmd=“xrandr--prop”
十六进制到十六进制ascii(){
echo-n“$1”| xxd-r-p
}
ascii_至_十六进制(){
echo-n“$1”| xxd-p
}
获取信息(){
否=0
声明OIFS=$IFS;
IFS=$fs
读取时-r输出连接hexn hexd;do
outs[no]=“${output}”
conns[no]=“${conn}”
名称[编号]=“$(十六进制到ascii“$hexn”)”
数据[否]=“$(十六进制到ascii“$hexd”)”
(++no))

已在Ubuntu 16.04、18.04上完成测试。(我知道现在回答这个问题已经太迟了,但这个解决方案与今天相关)

我连接了两个监视器。一个与笔记本电脑相连,另一个是外部显示器。一旦外部监视器插入或拔出,此命令将反映更改。您需要持续轮询。删除
--short
选项将提供更详细的信息

您可以使用以下后台作业轮询状态:

$ while true;
>  do
>   hwinfo --monitor --short;
>   sleep 2;
>  done >> monitor.log &
while true
循环无限次运行。
sleep 2
将循环的每次迭代暂停2秒。
hwinfo--monitor--short
的输出附加到
monitor.log
。此日志文件可以为您提供监视器插件和插件的活动历史记录

仅供参考:我正在使用一个后台(守护进程)python脚本,使用上述命令(以及其他类似命令)检测是否有人在计算机实验室的系统中执行某些硬件插件和插件。如果是这样,我会收到适当的通知,表明有人几乎实时插入/插入显示器、鼠标或键盘


关于
hwinfo
命令的更多信息是。它也是一个很好的源代码。

据我所知,您需要从特定于驱动程序的API中获取这些信息。nvidia中曾经有一些东西。您有什么卡?或者您需要通用的吗?@Miquel我的视频卡是ATI Radeon HD 5000。当然最好是获得更通用的解决方案。但是我当前机器的特定解决方案也将