Mendeteksi sesi X dalam skrip bash (.bashrc dll.)

16

Baru-baru ini saya menaruh di xset b off.bashrc saya. Sekarang saya terganggu oleh kesalahan yang muncul ketika saya masuk melalui tty atau melalui ssh, yaitu di luar sesi X.

Hal pertama yang terlintas di pikiran saya adalah [[ -z "$SOME_VAR" ]] && xset b off(well, ternyata variabel pengujian yang diset vs kosong adalah pertanyaan yang berbeda). Tetapi SOME_VAR mana yang benar?

Jadi saya membedakan setkeluaran tty dan keluaran urxvt setuntuk melihat variabel mana yang diatur dalam X dan hilang dalam tty. Seperti yang diharapkan, ada banyak perbedaan (daftar hanya yang tampaknya relevan bagi saya):

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

Yang mana yang paling benar dan universal untuk diuji untuk mendeteksi apakah saya dalam sesi X atau tidak? Sesuatu yang akan bekerja di banyak distro dan platform serta lingkungan desktop sebanyak mungkin?

Atau adakah cara yang lebih baik daripada menguji variabel lingkungan?

Alois Mahdal
sumber

Jawaban:

8

Cara sederhana dan efektif untuk menguji apakah server tampilan Anda tersedia dan valid adalah dengan mengujinya xhost. Anda tidak selalu dapat mengandalkan memeriksa nilai dalam DISPLAYvariabel karena itu dapat ditetapkan dengan nilai yang tidak valid.

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

Alasan saya melakukan ini adalah karena saya menjalankan beberapa skrip di pengguna saya crontabyang beroperasi pada layar ketika ada, tetapi bekerja secara berbeda ketika tidak. Di atas saya crontab, saya mengatur DISPLAYvariabel ke :0meskipun belum ada. Skrip pada crontabawal itu @rebootakan mulai terlepas dari apakah Anda memiliki tampilan atau tidak. Ini akan memungkinkan Anda untuk mendeteksi secara dinamis ketika layar Anda datang dan masuk dalam skrip yang sama.

CATATAN: Satu- >&satunya yang berfungsi di bash> = 4. Jika tidak gunakan> /dev/null 2>&1

cmevoli
sumber
Bagus, diuji juga dengan ssh -X; bekerja dengan baik!
Alois Mahdal
13

Saya pikir memeriksa DISPLAYakan menjadi pendekatan terbaik.

  • Ini menangani login jarak jauh (misalnya ssh -X).
  • Ini tersedia di sebagian besar - jika tidak semua - platform.
  • Ini tidak tergantung pada window manager / DE.
Renan
sumber
2
Saya juga mencari DISPLAY, atau hanya menekan pesan kesalahan secara umum. Berikan /dev/nullcinta dari waktu ke waktu.
frostschutz
3
@ frostschutz Tidak, saya hanya mencoba menjalankan bagian skrip yang relevan. Menekan pesan kesalahan tidak membuat langkah apa pun ke arah itu. Bahkan, hal itu dapat menimbulkan kebingungan serius yang memecahkan masalah hal - hal lain yang mungkin berpotensi pecah.
Alois Mahdal
1
Saya mulai menggunakan pendekatan ini tak lama setelah jawaban, dan itu bekerja dengan sempurna dengan sshs sederhana sampai sekarang, ketika saya mulai melakukan ssh -X--- untuk dapat menggunakan Vim lebih dari ssh sehingga konten yang dipilih oleh mode visual sampai ke clipboard X lokal, dimana Anda tidak perlu xserver di sisi server. Jadi DISPLAY akan disetel sebagai efek dari hanya memungkinkan penerusan, bahkan jika xserver dan xset tidak ada.
Alois Mahdal
Itu akan menjadi:if [[ $DISPLAY ]]; then … fi
Serge Stroobandt
1
DISPLAYVariabel Anda dapat mengarah ke tampilan yang sebenarnya tidak memiliki server X yang berjalan (misalnya ketika hardcode dalam skrip, atau server X dimatikan setelah variabel diatur).
n.st
6

Saya biasanya menggunakan TERMvariabel untuk menguji X dalam skrip saya.

TERMbiasanya diatur ke linuxpada TTY dan xtermX.
Saya menggunakan kata "biasanya" di sini, karena aplikasi seperti Layar GNU dan TMux tampaknya mengacaukan TERMVariable.

darnir
sumber
cobalah echo $TERMuntuk mencari tahu pengaturan kaya pada mashine Anda di berbagai konsol. Saya menggunakan [ $TERM == "linux" ] && echo do some stuffdi Ubuntu
rubo77
3

Ini harus bekerja dengan baik:

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

Jadi, ketika ini bernilai false ( [ ! -t 0 ]) kita berada dalam lingkungan GUI.

terdon
sumber
Dengan ini, saya mendapatkan hasil yang sama di kedua X dan di konsol, yaitu [ -t 0 ]dan [ -t 1 ]keduanya benar.
Emanuel Berg
Aneh, itu bekerja untuk saya ketika menghisap host yang jauh.
terdon
[ -t 0 ]berfungsi dengan baik pada konsol di Ubuntu (menggunakan CTRL ALT F1)
rubo77
0

Ada banyak cara Anda bisa melakukan itu.

Dalam bash, coba

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

Atau, di zsh, coba

#!/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
Emanuel Berg
sumber
Poin diambil, tetapi apakah Anda menguji kode Anda sebelum memposting? Yang pertama memiliki kesalahan sintaksis dan tidak benar-benar mendeteksi jika kita berada dalam sesi X sehingga echo 1jika X sedang berjalan dan Anda masuk melalui tty1-6 atau ssh. Yang lain selalu melakukan "hal-hal non-X" - Saya pikir itu ${CURRENT_VT[6]}berarti baris ke-6 daripada char ke-6.
Alois Mahdal
@AloisMahdal: Aha, barang-barang saya tidak berfungsi di bash (saya menggunakan zsh). Tidak memikirkan itu. Nah, Anda bisa mencobanya di zsh (tipe zsh) dan mungkin melakukan beberapa modifikasi jika Anda suka, untuk membuatnya bekerja di bash.
Emanuel Berg
@AloisMahdal: OK, saya mengubahnya. Adapun "login via tty1-6", seperti yang terjadi, itulah yang saya lakukan, dan kemudian saya menggunakan solusi kedua (di atas) dan mengatur variabel. Lihat ini .zshrc dan cari export VT. Saya menggunakan variabel untuk menyimpan Linux VT / console / tty saya (untuk zsh prompt) tetapi di X, saya hanya mengaturnya ke "X" (meskipun bukan VT). Tapi itu detail, Anda bisa menyelesaikannya dengan cara apa pun yang Anda suka di bash menggunakan prinsip yang sama.
Emanuel Berg
Saya telah menambahkan versi bash dari kondisi ke contoh kedua. Namun, saya pikir yang pertama masih salah. Mungkin memiliki ps mencetak hanya leluhur akan membantu. Saya tidak yakin apakah itu mungkin.
Alois Mahdal
@AloisMahdal: Periksa hasil edit. Itu cocok untuk saya, termasuk barang tty.
Emanuel Berg
0

if [[ $DISPLAY ]]

Di komputer yang sama, $DISPLAYakan kembali misalnya 0:0di terminal emulator, tetapi tidak ada di terminal nyata. Ini dapat dengan mudah diuji dengan CtrlAltF1versus CtrlAltF7.

Suatu bashkondisi berdasarkan $DISPLAYakan terlihat sebagai berikut:

if [[ $DISPLAY ]]; then 
  
fi
Serge Stroobandt
sumber