2012-05-08 40 views
11

情況:我正在使用多個顯示器,我想在bash中獲取他們的名字。目前我正在使用Ubuntu 10.04。Linux檢索顯示器名稱

我知道xrandr。從它我只能得到統計數據。我想要的是讀取數組中的所有顯示器名稱以與它們一起工作。

是否有一個明確的方式來做到這一點,而不從某種字符串的切割名字?一個明確的方法是從文件中讀取它們。一個不明確的方法是將xrandr輸出管道輸出爲某種功能,以從中刪除名稱。

+0

就我所知,您需要從驅動程序特定的API中獲取該信息。曾經在NVIDIA的東西。你有什麼牌?還是你需要一些通用的? – Miquel

+0

@Miquel我的視頻卡是ATI Radeon HD 5000.當然更好的辦法是獲得更通用的解決方案。但是我現有機器的具體解決方案也可以。 –

+0

我同意通過解析和解碼'xrandr --prop'或'xrandr --verbose'的輸出來獲取某些屬性並不是一個明確的方法,因爲xrandr的輸出格式可能會發生變化並且是無證的。我希望xrandr有辦法讀取給定輸出的各個屬性(例如exiftool可以讀取給定文件的單個元信息標籤)。 – jarno

回答

8

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 = ""; 
}' 
+2

對於Intel卡,edid文件在/ sys中提供。 'find/sys -name edid'。對於ATI來說,情況並非如此。無法驗證NVidia。 – Dave

+0

對於Ubuntu 12.04中的'xrandr',在第3行替換'EDID_DATA:'的'EDID:'。根據代碼中的評論,使用'| strings'時效果很好。 – MestreLion

+0

我發現xrandr比通過@Dave告訴的命令找到的文件更好地瞭解當前的EDID,如果您更改了監視器。 – jarno

1

您可以嘗試ddcprobe和/或get-edid

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

這沒有輸出需要。 xrandr會從xorg.conf文件輸出窗口名稱。這些名字是我所期望的。 –

2

如果你不想分析xrandr輸出,編寫使用libXrandr你只想要什麼得到一個C程序。如果您只想查詢信息,可以快速完成。 Read this document

如果你想獲得real監視器名稱,@ dtmilano解決方案的替代方法是使用libXrandr獲取監視器的EDID屬性,然後手動解析並打印(讀取EDID規範)。

xrandr source code

+1

如果您正在編寫C程序來執行此操作,您可以通過以下方式輕鬆獲得PNP ID(例如「SAM」=>「Samsung Electric Company」)的顯示器供應商名稱:https://github.com/ golightlyb/PNP-ID – HoboBen

0

您正在尋找EDID信息,這是沿着I²C總線傳遞,並通過您的視頻驅動程序解釋。正如dtmilano所說,從ddcprobe獲取編輯應該可以工作。

您也可以通過登錄你的X啓動這樣的信息:

startx -- -logverbose 6 

幾年前,我使用了一種叫做read-edid收集這些信息包。

讀-EDID包可以在Ubuntu已經,according to this blog post可從2009年

9

通過貝尼的回答啓發,這將根據EDID specification讀取使用xrandrEDID數據和提取監控名字,沒有任何需要的外部工具,如parse-edid

#!/bin/sh 
xrandr --verbose | awk ' 
/[:.]/ && hex { 
    sub(/.*000000fc00/, "", hex) 
    hex = substr(hex, 0, 26) "0a" 
    sub(/0a.*/, "0a", hex) 
    print hex 
    hex="" 
} 
hex { 
    gsub(/[ \t]+/, "") 
    hex = hex $0 
} 
/EDID.*:/ { 
    hex=" " 
}' | xxd -r -p 

用途awk精確地提取監控器名稱,並從EDID沒有多餘的垃圾,因此「幻數」之類000000fc00,260a。最後使用xxd將十六進制轉換爲ASCII,每行打印一個監視器名稱。

在此基礎上的解決方案我做了一個handy script to switch monitors,這也可以用來簡單地列出監控信息:

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

我用我的顯示器測試了內聯腳本,它什麼都不打印。我檢查了EDID並注意到它有兩個標記爲FCh的監視描述符,第一個是L1715S,第二個是空的。在我的筆記本電腦上,沒有用於集成顯示器的描述符,但是兩個標記爲FEh的描述符顯然包含品牌名稱CPT和型號名稱CLAA102NA0A。 – jarno

+0

至少有一個'FCh'條目是規範所必需的,所以它的怪異你的筆記本電腦不包含一個......'FEh'代表「未指定的文本」,基本上是一個自由文本字段,所以我不能依靠它包含相關信息。關於不打印任何內容,請打開粘貼兩個EDID的問題,以便我們可以調整您的案例的腳本。 – MestreLion

+0

也許筆記本電腦顯示屏沒有名稱,因爲它不是一個單獨的客戶產品。 – jarno

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 <[email protected]> 
# 
# 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 
+0

偉大的腳本!不知道第四個參數應該是什麼,它與我的顯示器保持空白。但是,如果我將000000fe00更改爲000000ff00,則會顯示我的顯示器序列號。這對於檢測哪個顯示器連接到什麼連接器很有用。 (根據wiki,000000fe00是未指定的文本字段。) – Geeklab

1

適用於Ubuntu 16.04。 (我知道它太遲迴答,但這個解決方案今天是相關的)

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

我有兩個監視器連接。一個與筆記本電腦和另一個是外部顯示器。只要外接顯示器插入或拔出,​​該命令就會反映出這種變化。你不斷需要投票。刪除--short選項可提供更詳細的信息。

您可以用下面的後臺作業輪詢狀態:

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

while true循環運行無限次。 sleep 2將循環的每次迭代暫停2秒。 hwinfo --monitor --short的輸出附加到monitor.log。該日誌文件可以爲您提供監視器插件和插件的活動歷史記錄。我使用上述命令(和其他類似命令)使用背景(deamon)python腳本來檢測某人是否在計算機實驗室中使用某些硬件插件和插件。如果是這樣,我會收到適當的通知,指出某人幾乎是實時地將其插入顯示器,鼠標或鍵盤中!

有關更多信息hwinfo command is here。其man page也是一個很好的來源。