การตรวจจับเซสชัน X ในสคริปต์ทุบตี (.bashrc ฯลฯ )


16

เมื่อเร็ว ๆ นี้ฉันใส่xset b off. bashrc ของฉัน ตอนนี้ฉันรำคาญกับข้อผิดพลาดที่ปรากฏขึ้นเมื่อฉันเข้าสู่ระบบผ่านทาง tty หรือผ่าน ssh คือนอกเซสชั่น X

สิ่งแรกที่อยู่ในใจของฉันคือ[[ -z "$SOME_VAR" ]] && xset b off(เอาล่ะปรากฎว่าตัวแปรทดสอบที่ตั้งไว้และความว่างเปล่าเป็นคำถามที่แตกต่างกัน) แต่ SOME_VAR ใดที่ถูกต้อง

ดังนั้นฉันจึงแยกsetเอาท์พุทของ tty และเอาต์พุตของ urxvt setเพื่อดูว่าตัวแปรใดถูกตั้งค่าเป็น X และหายไปใน tty ตามที่คาดไว้มีความแตกต่างค่อนข้างมาก (แสดงเฉพาะสิ่งที่ดูเหมือนเกี่ยวข้องกับฉัน):

  • DESKTOP_SESSION
  • DISPLAY
  • GDMSESSION
  • SESSION_MANAGER
  • WINDOWID
  • WINDOWPATH
  • XAUTHORITY
  • XDG_SESSION_COOKIE
  • XDG_CONFIG_DIRS
  • XDG_DATA_DIRS
  • XDG_MENU_PREFIX

ข้อใดที่ถูกต้องและเป็นสากลมากที่สุดในการทดสอบเพื่อตรวจสอบว่าฉันอยู่ในช่วง X หรือไม่? มีสิ่งใดบ้างที่สามารถใช้ข้ามแพลตฟอร์มและแพลตฟอร์มและสภาพแวดล้อมเดสก์ท็อปได้มากเท่าที่จะเป็นไปได้

หรือมีวิธีที่ดีกว่าการทดสอบตัวแปรสภาพแวดล้อม?

คำตอบ:


8

วิธีที่ง่ายและมีประสิทธิภาพในการทดสอบว่าเซิร์ฟเวอร์การแสดงผลของคุณพร้อมใช้งานและถูกต้องคือการทดสอบด้วย xhostที่เรียบง่ายและมีประสิทธิภาพในการทดสอบว่าเซิร์ฟเวอร์ที่แสดงของคุณที่มีอยู่และที่ถูกต้องคือการทดสอบด้วยคุณไม่สามารถพึ่งพาการตรวจสอบค่าในDISPLAYตัวแปรได้ตลอดเวลาเนื่องจากสามารถตั้งค่าด้วยค่าที่ไม่ถูกต้อง

if xhost >& /dev/null ; then echo "Display exists"
else echo "Display invalid" ; fi

เหตุผลที่ฉันทำเช่นนี้เป็นเพราะฉันเรียกใช้สคริปต์หลายตัวในผู้ใช้ของฉันcrontabที่ทำงานบนจอแสดงผลเมื่อมันมีอยู่ แต่ทำงานแตกต่างกันเมื่อไม่ได้ ที่ด้านบนของฉันcrontabฉันตั้งค่าDISPLAYตัวแปรเป็น:0แม้ว่ามันจะยังไม่มี สคริปต์crontabที่เริ่มต้นด้วย@rebootจะเริ่มต้นไม่ว่าคุณจะมีจอแสดงผลหรือไม่ก็ตาม สิ่งนี้จะช่วยให้คุณตรวจจับแบบไดนามิกเมื่อหน้าจอของคุณมาถึงและไปอยู่ในสคริปต์เดียวกัน

หมายเหตุ: ใช้>&งานได้ในbash> = 4 เท่านั้นมิฉะนั้นใช้> /dev/null 2>&1


ดีทดสอบด้วยssh -X; ทำงานได้ดี!
Alois Mahdal

13

ฉันคิดว่าการตรวจสอบDISPLAYเป็นวิธีที่ดีที่สุด

  • มันจัดการการเข้าสู่ระบบระยะไกล (เช่น ssh -X)
  • มันมีอยู่ในแพลตฟอร์มส่วนใหญ่ - ถ้าไม่ใช่ทั้งหมด
  • เป็นอิสระจากตัวจัดการหน้าต่าง / DE

2
ฉันจะไปDISPLAYด้วยหรือเพียงแค่ระงับข้อความแสดงข้อผิดพลาดโดยทั่วไป ให้/dev/nullความรักบ้างเป็นครั้งคราว
frostschutz

3
@frostschutz ไม่ฉันพยายามเรียกใช้เฉพาะส่วนที่เกี่ยวข้องของสคริปต์ การระงับข้อความแสดงข้อผิดพลาดไม่ได้ทำขั้นตอนใด ๆ ในทิศทางนั้น ในความเป็นจริงมันสามารถนำไปสู่ความสับสนอย่างรุนแรงในการแก้ไขปัญหาอื่น ๆที่อาจแตกหัก
Alois Mahdal

1
ฉันเริ่มใช้วิธีการนี้หลังจากคำตอบไม่นานและมันทำงานได้อย่างสมบูรณ์แบบด้วยsshs อย่างง่ายจนถึงตอนนี้เมื่อฉันเริ่มทำssh -X--- เพื่อให้สามารถใช้ Vim บน ssh เพื่อให้เนื้อหาที่เลือกโดยโหมดภาพไปที่คลิปบอร์ด X ในเครื่องซึ่งคุณไม่ต้องการ xserverที่ฝั่งเซิร์ฟเวอร์ ดังนั้น DISPLAY จึงได้รับการตั้งค่าเช่นเดียวกับการเปิดใช้งานการส่งต่อแม้ว่า xserver และ xset จะไม่มีอยู่
Alois Mahdal

นั่นจะเป็น:if [[ $DISPLAY ]]; then … fi
Serge Stroobandt

1
DISPLAYตัวแปรของคุณสามารถชี้ไปที่จอแสดงผลที่ไม่มีเซิร์ฟเวอร์ X ทำงานอยู่ (ตัวอย่างเช่นเมื่อฮาร์ดโค้ดในสคริปต์หรือเซิร์ฟเวอร์ X ปิดตัวลงหลังจากตั้งค่าตัวแปรแล้ว)
n.st

6

ฉันมักจะใช้TERMตัวแปรเพื่อทดสอบ X ในสคริปต์ของฉัน

TERMมักจะถูกตั้งค่าเป็นlinuxTTY และxtermX
ฉันใช้คำว่า "ปกติ" ที่นี่เนื่องจากแอปพลิเคชันเช่น GNU Screen และ TMux ดูเหมือนจะยุ่งกับTERMVariable


ลองecho $TERMค้นหาการตั้งค่า richt บน mashine ของคุณในคอนโซลที่แตกต่างกัน ฉันใช้[ $TERM == "linux" ] && echo do some stuffบน Ubuntu
rubo77

3

สิ่งนี้จะทำงานได้ดีอย่างสมบูรณ์:

[ ! -t 0 ] && xset b off                                  

http://tldp.org/LDP/abs/html/fto.html

-t

    file (descriptor) is associated with a terminal device

    This test option may be used to check whether the stdin [ -t 0 ] 
    or stdout [ -t 1 ] in a given script is a terminal.

ดังนั้นเมื่อสิ่งนี้ประเมินว่าเป็นเท็จ ( [ ! -t 0 ]) เราอยู่ในสภาพแวดล้อม GUI


ด้วยสิ่งนี้ฉันได้ผลลัพธ์เดียวกันทั้ง X และในคอนโซลคือ[ -t 0 ]และ[ -t 1 ]ทั้งสองเป็นจริง
Emanuel Berg

แปลกมันใช้งานได้สำหรับฉันเมื่อ sshing เป็นโฮสต์ระยะไกล
terdon

[ -t 0 ]ทำงานได้ดีบนคอนโซลใน Ubuntu (ใช้ CTRL ALT F1)
rubo77

0

มีหลายวิธีที่คุณสามารถทำได้

ลองทุบตี

function xruns {
    if [[ `pstree -As $$ | grep xinit | wc -l` == 1 ]]; then
        echo "You are in X."
    else
        echo "You are not in X."
    fi
}

หรือลอง zsh

#!/usr/bin/zsh

CURRENT_VT=`tty`

if [[ ${CURRENT_VT[6]} == "p" ]];        # or `${CURRENT_VT:5:1}` in bash
then
   # X stuff
else 
   # non-X stuff      
fi

ชี้ไปแล้ว แต่คุณทดสอบโค้ดก่อนโพสต์หรือไม่ คนแรกมีข้อผิดพลาดทางไวยากรณ์และไม่จริงตรวจพบว่าเราอยู่ในเซสชั่น X ดังนั้นมันจะecho 1ถ้า X กำลังทำงานอยู่และคุณเข้าสู่ระบบผ่าน tty1-6 หรือ ssh อีกอันหนึ่งทำ "สิ่งที่ไม่ใช่ X" เสมอ - ฉันคิดว่านั่น${CURRENT_VT[6]}หมายถึงบรรทัดที่ 6 มากกว่าตัวอักษรตัวที่ 6
Alois Mahdal

@AloisMahdal: Aha สิ่งของของฉันไม่ทำงานในการทุบตี (ฉันใช้ zsh) ไม่ได้คิดอย่างนั้น คุณสามารถลองเป็น zsh (ชนิดzsh) และอาจทำการแก้ไขบางอย่างถ้าคุณชอบเพื่อให้มันทำงานได้อย่างยอดเยี่ยม
Emanuel Berg

@AloisMahdal: ตกลงฉันเปลี่ยนมัน สำหรับ "เข้าสู่ระบบผ่าน tty1-6" ตามที่เกิดขึ้นนั่นคือสิ่งที่ฉันทำแล้วฉันจะใช้วิธีที่สอง (ด้านบน) และตั้งค่าตัวแปร ตรวจสอบนี้ และค้นหา.zshrc export VTฉันใช้ตัวแปรเพื่อเก็บสิ่งที่ Linux VT / console / tty ฉันอยู่ (สำหรับพร้อมท์ zsh) แต่ใน X ฉันเพิ่งตั้งเป็น "X" (แม้ว่าจะไม่ใช่ VT) แต่นั่นคือรายละเอียดคุณสามารถทำงานในแบบที่คุณต้องการโดยใช้หลักการเดียวกัน
Emanuel Berg

ฉันได้เพิ่มเวอร์ชัน bash ของเงื่อนไขลงในตัวอย่างที่สอง อย่างไรก็ตามฉันคิดว่าอันแรกยังผิด บางทีการพิมพ์ ps บรรพบุรุษเท่านั้นที่จะช่วยได้ ฉันไม่แน่ใจว่าเป็นไปได้หรือไม่
Alois Mahdal

@AloisMahdal: ตรวจสอบการแก้ไข ที่ทำเพื่อฉันรวมถึงสิ่ง tty
Emanuel Berg

0

if [[ $DISPLAY ]]

บนคอมพิวเตอร์เครื่องเดียวกัน$DISPLAYจะส่งคืนตัวอย่าง0:0ในเทอร์มินัลอีมูเลเตอร์ แต่ไม่มีอะไรในเทอร์มินัลตัวจริง สิ่งนี้สามารถทดสอบได้ง่ายCtrlAltF1เมื่อเทียบกับCtrlAltF7เมื่อเทียบกับ

bashสภาพขึ้นอยู่กับ$DISPLAYจะมีลักษณะดังต่อไปนี้:

if [[ $DISPLAY ]]; then 
  
fi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.