情況:我正在使用多個顯示器,我想在bash中獲取他們的名字。目前我正在使用Ubuntu 10.04。Linux檢索顯示器名稱
我知道xrandr。從它我只能得到統計數據。我想要的是讀取數組中的所有顯示器名稱以與它們一起工作。
是否有一個明確的方式來做到這一點,而不從某種字符串的切割名字?一個明確的方法是從文件中讀取它們。一個不明確的方法是將xrandr輸出管道輸出爲某種功能,以從中刪除名稱。
情況:我正在使用多個顯示器,我想在bash中獲取他們的名字。目前我正在使用Ubuntu 10.04。Linux檢索顯示器名稱
我知道xrandr。從它我只能得到統計數據。我想要的是讀取數組中的所有顯示器名稱以與它們一起工作。
是否有一個明確的方式來做到這一點,而不從某種字符串的切割名字?一個明確的方法是從文件中讀取它們。一個不明確的方法是將xrandr輸出管道輸出爲某種功能,以從中刪除名稱。
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 = "";
}'
對於Intel卡,edid文件在/ sys中提供。 'find/sys -name edid'。對於ATI來說,情況並非如此。無法驗證NVidia。 – Dave
對於Ubuntu 12.04中的'xrandr',在第3行替換'EDID_DATA:'的'EDID:'。根據代碼中的評論,使用'| strings'時效果很好。 – MestreLion
我發現xrandr比通過@Dave告訴的命令找到的文件更好地瞭解當前的EDID,如果您更改了監視器。 – jarno
您可以嘗試ddcprobe
和/或get-edid
$ sudo apt-get install xresprobe read-edid
$ sudo ddcprobe
$ sudo get-edid
這沒有輸出需要。 xrandr會從xorg.conf文件輸出窗口名稱。這些名字是我所期望的。 –
如果你不想分析xrandr
輸出,編寫使用libXrandr
你只想要什麼得到一個C程序。如果您只想查詢信息,可以快速完成。 Read this document。
如果你想獲得real監視器名稱,@ dtmilano解決方案的替代方法是使用libXrandr獲取監視器的EDID屬性,然後手動解析並打印(讀取EDID規範)。
如果您正在編寫C程序來執行此操作,您可以通過以下方式輕鬆獲得PNP ID(例如「SAM」=>「Samsung Electric Company」)的顯示器供應商名稱:https://github.com/ golightlyb/PNP-ID – HoboBen
您正在尋找EDID信息,這是沿着I²C總線傳遞,並通過您的視頻驅動程序解釋。正如dtmilano所說,從ddcprobe獲取編輯應該可以工作。
您也可以通過登錄你的X啓動這樣的信息:
startx -- -logverbose 6
幾年前,我使用了一種叫做read-edid收集這些信息包。
讀-EDID包可以在Ubuntu已經,according to this blog post可從2009年
通過貝尼的回答啓發,這將根據EDID specification讀取使用xrandr
的EDID數據和提取監控名字,沒有任何需要的外部工具,如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
,26
和0a
。最後使用xxd
將十六進制轉換爲ASCII,每行打印一個監視器名稱。
在此基礎上的解決方案我做了一個handy script to switch monitors,這也可以用來簡單地列出監控信息:
$ monitor-switch --list
Connected monitors:
# DFP5 HDMI HT-R391
# DFP7 DVI-I DELL U2412M
我用我的顯示器測試了內聯腳本,它什麼都不打印。我檢查了EDID並注意到它有兩個標記爲FCh的監視描述符,第一個是L1715S,第二個是空的。在我的筆記本電腦上,沒有用於集成顯示器的描述符,但是兩個標記爲FEh的描述符顯然包含品牌名稱CPT和型號名稱CLAA102NA0A。 – jarno
至少有一個'FCh'條目是規範所必需的,所以它的怪異你的筆記本電腦不包含一個......'FEh'代表「未指定的文本」,基本上是一個自由文本字段,所以我不能依靠它包含相關信息。關於不打印任何內容,請打開粘貼兩個EDID的問題,以便我們可以調整您的案例的腳本。 – MestreLion
也許筆記本電腦顯示屏沒有名稱,因爲它不是一個單獨的客戶產品。 – jarno
我知道這是一個骯髒的方式,但它給了我一些顯示器型號甚至優於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
偉大的腳本!不知道第四個參數應該是什麼,它與我的顯示器保持空白。但是,如果我將000000fe00更改爲000000ff00,則會顯示我的顯示器序列號。這對於檢測哪個顯示器連接到什麼連接器很有用。 (根據wiki,000000fe00是未指定的文本字段。) – Geeklab
適用於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腳本來檢測某人是否在計算機實驗室中使用某些硬件插件和插件。如果是這樣,我會收到適當的通知,指出某人幾乎是實時地將其插入顯示器,鼠標或鍵盤中!
就我所知,您需要從驅動程序特定的API中獲取該信息。曾經在NVIDIA的東西。你有什麼牌?還是你需要一些通用的? – Miquel
@Miquel我的視頻卡是ATI Radeon HD 5000.當然更好的辦法是獲得更通用的解決方案。但是我現有機器的具體解決方案也可以。 –
我同意通過解析和解碼'xrandr --prop'或'xrandr --verbose'的輸出來獲取某些屬性並不是一個明確的方法,因爲xrandr的輸出格式可能會發生變化並且是無證的。我希望xrandr有辦法讀取給定輸出的各個屬性(例如exiftool可以讀取給定文件的單個元信息標籤)。 – jarno