Phát hiện phiên X trong tập lệnh bash (.bashrc, v.v.)


16

Gần đây tôi đưa xset b offvào .bashrc của tôi. Bây giờ tôi cảm thấy khó chịu vì lỗi đã bật lên khi tôi đăng nhập qua tty hoặc qua ssh, tức là ngoài phiên X.

Điều đầu tiên xuất hiện trong đầu tôi là [[ -z "$SOME_VAR" ]] && xset b off(ừm, hóa ra biến kiểm tra được đặt so với trống là một câu hỏi khác). Nhưng SOME_VAR nào là đúng?

Vì vậy, tôi đã setphân tách đầu ra của tty và đầu ra của urxvt setđể xem biến nào được đặt trong X và thiếu trong tty. Đúng như dự đoán, có khá nhiều sự khác biệt (chỉ liệt kê những thứ có vẻ phù hợp với tôi):

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

Cái nào là chính xác và phổ biến nhất để kiểm tra để phát hiện xem tôi có tham gia phiên X hay không? Một cái gì đó sẽ hoạt động trên càng nhiều distro và nền tảng và môi trường máy tính để bàn càng tốt?

Hoặc có cách nào tốt hơn so với thử nghiệm các biến môi trường?

Câu trả lời:


8

Một cách đơn giản và hiệu quả để kiểm tra rằng máy chủ hiển thị của bạn có sẵn và hợp lệ là kiểm tra nó với xhost. Bạn không thể luôn luôn dựa vào việc kiểm tra giá trị trong DISPLAYbiến vì nó có thể được đặt với giá trị không hợp lệ.

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

Lý do tôi làm điều này là vì tôi chạy một số tập lệnh trong người dùng của tôi crontabhoạt động trên màn hình khi nó tồn tại, nhưng hoạt động khác nhau khi không. Ở đầu của tôi crontab, tôi đặt DISPLAYbiến thành :0mặc dù nó chưa tồn tại. Các tập lệnh crontabbắt đầu bằng @rebootsẽ bắt đầu bất kể bạn có hiển thị hay không. Điều này sẽ cho phép bạn tự động phát hiện khi màn hình của bạn đến và đi trong cùng một tập lệnh.

LƯU Ý: >&Chỉ hoạt động trong bash> = 4. Nếu không sử dụng> /dev/null 2>&1


Đẹp, thử nghiệm cũng với ssh -X; hoạt động tốt
Alois Mahdal

13

Tôi nghĩ rằng kiểm tra DISPLAYsẽ là cách tiếp cận tốt nhất.

  • Nó xử lý đăng nhập từ xa (ví dụ ssh -X).
  • Nó có sẵn trong hầu hết - nếu không phải tất cả - nền tảng.
  • Nó độc lập với trình quản lý cửa sổ / DE.

2
Tôi cũng sẽ đi DISPLAY, hoặc đơn giản là ngăn chặn thông báo lỗi nói chung. Cho /dev/nullmột số tình yêu theo thời gian.
frostschutz

3
@frostschutz Không, tôi đang cố gắng chỉ chạy một phần có liên quan của tập lệnh. Việc loại bỏ các thông báo lỗi không thực hiện bất kỳ bước nào theo hướng đó. Trong thực tế, nó có thể dẫn đến sự nhầm lẫn nghiêm trọng khắc phục sự cố những thứ khác có khả năng phá vỡ.
Alois Mahdal

1
Tôi đã bắt đầu sử dụng phương pháp này ngay sau câu trả lời và nó hoạt động hoàn hảo với các đơn giản sshcho đến bây giờ, khi tôi bắt đầu thực hiện ssh -X--- để có thể sử dụng Vim qua ssh để nội dung được chọn bởi chế độ trực quan được chuyển sang bảng tạm X cục bộ, trong đó bạn không cần xserver ở phía máy chủ. Vì vậy, HIỂN THỊ được thiết lập giống như hiệu ứng đơn giản là cho phép chuyển tiếp, ngay cả khi xserver và xset không xuất hiện.
Alois Mahdal


1
DISPLAYBiến của bạn có thể trỏ đến một màn hình không thực sự có máy chủ X đang chạy (ví dụ: khi nó được mã hóa cứng trong tập lệnh hoặc máy chủ X bị tắt sau khi biến được đặt).
n.st

6

Tôi thường sử dụng TERMbiến để kiểm tra X trong các tập lệnh của mình.

TERMthường được đặt thành linuxtrên TTY và xtermtrên X.
Tôi sử dụng từ "thường" ở đây, vì các ứng dụng như GNU Screen và TMux dường như gây rối với TERMBiến.


cố gắng echo $TERMtìm hiểu cài đặt richt trên mashine của bạn trong các bảng điều khiển khác nhau. Tôi sử dụng [ $TERM == "linux" ] && echo do some stufftrên Ubuntu
rubo77

3

Điều này sẽ hoạt động hoàn toàn tốt:

[ ! -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.

Vì vậy, khi điều này đánh giá thành false ( [ ! -t 0 ]) chúng ta đang ở trong môi trường GUI.


Với điều này, tôi nhận được cùng một kết quả trong cả X và trong bảng điều khiển, cụ thể [ -t 0 ][ -t 1 ]đều đúng.
Emanuel Berg

Thật kỳ lạ, nó hoạt động với tôi khi sshing vào một máy chủ từ xa.
terdon

[ -t 0 ]hoạt động tốt trên bảng điều khiển trong Ubuntu (sử dụng CTRL ALT F1)
rubo77

0

Có nhiều cách bạn có thể làm điều đó.

Trong bash, hãy thử

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

Hoặc, trong zsh, hãy thử

#!/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

Điểm lấy, nhưng bạn có kiểm tra mã của bạn trước khi đăng? Cái đầu tiên có lỗi cú pháp và không thực sự phát hiện nếu chúng ta đang ở trong phiên X nên echo 1nếu X đang chạy và bạn đăng nhập thông qua tty1-6 hoặc ssh. Một cái khác luôn luôn làm "công cụ không phải X" - tôi nghĩ điều đó ${CURRENT_VT[6]}có nghĩa là dòng thứ 6 chứ không phải thứ 6 char.
Alois Mahdal

@AloisMahdal: Aha, công cụ của tôi không hoạt động trong bash (tôi sử dụng zsh). Không nghĩ về điều đó. Chà, bạn có thể thử nó trong zsh (loại zsh) và có thể thực hiện một số sửa đổi nếu bạn thích nó, để làm cho nó hoạt động trong bash.
Emanuel Berg

@AloisMahdal: OK, tôi đã thay đổi nó. Đối với "đăng nhập qua tty1-6", như nó xảy ra, đó là những gì tôi làm, và sau đó tôi sử dụng giải pháp thứ hai (ở trên) và đặt một biến. Kiểm tra này .zshrc và tìm kiếm export VT. Tôi sử dụng biến để giữ những gì Linux VT / console / tty tôi đang sử dụng (đối với dấu nhắc zsh) nhưng trong X, tôi chỉ đặt nó thành "X" (mặc dù không phải là VT). Nhưng đó là chi tiết, bạn có thể tìm ra bất kỳ cách nào bạn muốn trong bash bằng cách sử dụng cùng một nguyên tắc.
Emanuel Berg

Tôi đã thêm phiên bản bash của điều kiện vào ví dụ thứ hai. Tuy nhiên, tôi nghĩ rằng cái đầu tiên vẫn sai. Có lẽ có ps in chỉ tổ tiên sẽ giúp. Tôi không chắc chắn nếu nó có thể, mặc dù.
Alois Mahdal

@AloisMahdal: Kiểm tra chỉnh sửa. Điều đó làm cho tôi, bao gồm cả những thứ tty.
Emanuel Berg

0

if [[ $DISPLAY ]]

Trên cùng một máy tính, $DISPLAYsẽ trả về ví dụ 0:0trong trình giả lập thiết bị đầu cuối, nhưng không có gì trong một thiết bị đầu cuối thực sự. Điều này có thể dễ dàng được kiểm tra với CtrlAltF1so với CtrlAltF7.

Một bashđiều kiện dựa trên $DISPLAYsẽ trông như sau:

if [[ $DISPLAY ]]; then 
  
fi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.