Виявлення X сеансу в bash-скрипті (.bashrc тощо)


16

Нещодавно я поклав xset b offдо свого .bashrc. Тепер мене дратує помилка, що з'являється, коли я входжу через tty чи через ssh, тобто поза сеансом X.

Перше, що мені прийшло в голову, було [[ -z "$SOME_VAR" ]] && xset b off(ну, виявляється, тестування змінної, встановленої проти порожнього - це інше питання). Але який SOME_VAR є правильним?

Тож я setрозширив setвихід tty та вихід urxvt, щоб побачити, які змінні встановлені в 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; працює чудово!
Алоїз Магдал

13

Я думаю, що перевірка DISPLAYбула б найкращим підходом.

  • Він обробляє віддалені входи (наприклад, ssh -X).
  • Він доступний на більшості - якщо не на всіх - платформах.
  • Це не залежить від менеджера вікон / DE.

2
Я також хотів би DISPLAYабо просто придушити повідомлення про помилку взагалі. /dev/nullЧас від часу даруйте любов.
frostschutz

3
@frostschutz Ні, я намагаюся запустити лише відповідну частину сценарію. Придушення повідомлень про помилки не робить жодного кроку в цьому напрямку. Насправді це може призвести до серйозної плутанини при усуненні інших речей, які потенційно можуть зірватися.
Алоїз Магдал

1
Я почав використовувати цей підхід незабаром після відповіді, і він прекрасно працював з простими sshs до цих пір, коли я почав робити ssh -X--- щоб мати можливість використовувати Vim over ssh, щоб вміст, обраний у візуальному режимі, потрапляв до місцевого буфера обміну X, для якого вам не потрібен xserver на стороні сервера. Таким чином, DISPLAY встановлюється так само, як ефект просто включення переадресації, навіть якщо xserver та xset відсутні.
Алоїз Магдал


1
Ваша DISPLAYзмінна може вказувати на дисплей, на якому насправді не працює X-сервер (наприклад, коли він жорстко кодується в сценарії або X-сервер був закритий після встановлення змінної).
n.st

6

Зазвичай я використовую TERMзмінну для тестування на X у своїх сценаріях.

TERMзазвичай встановлено linuxна TTY і xtermна X.
Я тут використовую слово "зазвичай", оскільки такі програми, як GNU Screen і TMux, схоже, псуються зі TERMзмінною.


спробуйте echo $TERMдізнатися налаштування Richt на вашому машині в різних консолях. Я використовую [ $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.

Отже, коли це оцінюється як false ( [ ! -t 0 ]), ми перебуваємо в середовищі GUI.


Завдяки цьому я отримую однаковий результат і в X, і в консолі, а саме - [ -t 0 ]і те, [ -t 1 ]і інше.
Емануель Берг

Як не дивно, він працює для мене, коли перебирається на віддалений хост.
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-й знак.
Алоїз Магдал

@AloisMahdal: Ага, мої речі не працюють в bash (я використовую zsh). Не думав про це. Ну, ви можете спробувати його в zsh (type zsh) і, можливо, зробити деякі зміни, якщо вам це подобається, щоб змусити його працювати в bash.
Емануель Берг

@AloisMahdal: Гаразд, я змінив це. Що стосується "входу через tty1-6", то, як це відбувається, я це роблю, і тоді я використовую друге рішення (вище) і встановлюю змінну. Перевірте це .zshrc і шукайте export VT. Я використовую змінну, щоб утримувати те, в якому Linux VT / console / tty я перебуваю (для запиту zsh), але в X, я просто встановив його на "X" (хоча це не VT). Але це деталі, ви можете це зробити будь-яким способом, який вам захочеться в баші, використовуючи той самий принцип.
Емануель Берг

До другого прикладу я додав bash версію умови. Однак я думаю, що перший все-таки помиляється. Можливо, допомога мати друк на PS лише предкам . Я не впевнений, чи можливо це можливо.
Алоїз Магдал

@AloisMahdal: Перевірте правки. Це робить для мене, включаючи tty речі.
Емануель Берг

0

if [[ $DISPLAY ]]

На тому ж комп’ютері $DISPLAYповернеться, наприклад, 0:0в емулятор терміналу, але нічого в реальному терміналі. Це можна легко перевірити CtrlAltF1порівняно зCtrlAltF7 .

bashСтан на основі $DISPLAYбуде виглядати наступним чином :

if [[ $DISPLAY ]]; then 
  
fi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.