Як я можу зрозуміти, чи перебуваю я на екрані?


78

Коли я використовую екран у Linux, як я можу зрозуміти, чи перебуваю я на екрані чи ні? Я міг би це зробити, exitі я вийшов з екрану, якщо був у ньому, але якби не був, то в підсумку закрию свій термінал.

Роблячи це screen -r, я міг перевірити, чи підключені інші екрани, але як я можу дізнатися, чи мій поточний термінал є одним із цих прикріплених екранів?


Варто зазначити, що якщо ви знаходитесь на екрані та запускаєте screen -r, він повідомить вас, що ви знаходитесь на екрані (або, якщо екранів немає, це повідомляє вам, що ви не можете бути на одному), і якщо ви перебуваючи не на екрані, і прив’язавшись до нього, ви можете просто набрати C-a(або будь- яка інша клавіша на екрані) +, dщоб вийти з екрану, який ви щойно ввели. Отже, це один простий спосіб сказати. Однак не варто давати відповідь, оскільки я припускаю, що OP вже знав / відхилив цей варіант.
Парфіанський постріл

Відповіді:


129

Перевірте $STY . Якщо він нульовий, ви перебуваєте на "справжньому" терміналі. Якщо він щось містить, це назва екрана, на якому ви перебуваєте.

Якщо ви не на екрані:

eric@dev ~ $ echo $STY
eric@dev ~ $ 

Якщо ви знаходитесь на екрані:

eric@dev ~ $ echo $STY
2026.pts-0.ip-10-0-1-71

5
Що означає STY?
Steven You

2
@StevenYou Все, що я коли-небудь знайшов, це "альтернативне ім'я сокета" . Що насправді не пояснює вибір імені змінної.
ahruss

1
це працює, якщо ви перебуваєте на тій самій машині, з якою ви запускали екран. Якщо ви ssh на новій машині, вам потрібно буде передати змінну. (тобто. ssh user @ host "STY = $ STY")
Аарон Оммен,

9
@StevenYou, ймовірно, розшифровується як "Screen TYpewriter" або "Socket TYpewriter". TTY означає "TeleTYpewriter", PTY означає "Pseudoterminal TYpewriter". Вони, напевно, вважали, що це досить очевидно, їм не потрібно чітко згадувати свої міркування. Як засвідчує ця розмова, вони помилялися.
Парфіанський постріл

3
Наскільки це варте, це, здається, не працює з tmux на osx, тоді як перевірка на основі "$ TERM" працює.
Андрій Барсан,

16

Ще один спосіб, яким я це зробив, - повторити $ TERM.

 $ echo $TERM
 screen

Оскільки я в кінцевому підсумку роблю це багато, я додав псевдонім у свій файл .bashrc:

alias trm='echo $TERM'

Таким чином, незалежно від того, на екрані чи ні, якщо я просто виконую "trm", він покаже мені, чи перебуваю я на ЕКРАНІ чи деінде (зазвичай XTERM).


Для уточнення, під Linux значення $ TERM буде, screen.linuxколи буде на екрані.
Парфіанський постріл

щасливо, що значення $ TERM під tmux - це "екран" (принаймні в OS X)
Майкл

1
Насправді, Parthian, принаймні у всіх останніх OS-X / macOS, останніх CentOS та Ubuntu (принаймні 14.04), $ TERM повертає просто "екран". Не впевнені, яку версію ОС / ядра / оболонки ви бачите "screen.linux" під.
JJC

14

Альтернативний підхід, щоб перевірити, чи перебуваєте ви на екрані.

тип:

Ctrl-a ?

Якщо ви бачите підказку на екрані, ви перебуваєте на екрані.

В іншому випадку ви отримаєте знак питання "?" у підказці.


1
Звичайно, це передбачає, що Ctrl+ aє символом команди для екрана. Хоча це буде правдою для більшості людей, варто зазначити, що символ команди може бути замінений -eпрапором, тому це не завжди буде працювати.
Парфіанський постріл

Це чудово працює (Ctrl +, наприклад, "втеча", наприклад). Хоча, я думаю, це може перенести курсор на початок поточного рядка, якщо ви цього не зробите на екрані ...: |
rogerdpack

2

Оскільки всі інші методи тут покладаються на змінні середовища (які можна просто замінити) або командний символ для екрана (який також можна замінити), найбезпечнішим способом перевірки буде перелік усіх предків поточного процесу.

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | grep screen | wc -l

Якщо він друкує 1, то поточний процес, який ви запускаєте, має попередника зі словом 'екран' в назві виконуваного файлу, інакше цього не було.

Більш зручний видимий огляд можна отримати у:

pstree --show-parents -p $$ | head -n 1 | sed 's/\(.*\)+.*/\1/' | less

1
Цікавий підхід. Однак вам не потрібно нічого з цього -p, head -n 1 | sed 's/\(.*\)+.*/\1/'і wc -lя б запропонував додати -w до grep, щоб бути у безпеці (він буде відповідати лише програмі з іменем "screen", а не "screenish"). Отже, це остання команда pstree --show-parents $$|grep -w screen. Однак якщо хтось возиться із вашими змінними середовища, він міг возитися і з ім'ям виконуваного файлу :)
ndemou

2

Моє рішення проблеми набагато простіше: одне натискання TAB змушує моргати весь термінал (швидка інверсія відео), якщо ви знаходитесь у GNU Screen .

Перевірено, працюючи на більшості Linux (Ubuntu, Kali, Debian, RaspBerry ... тощо) та FreeBSD , графічному інтерфейсі та будь-якому терміналі, локальному або віддаленому, включаючи CtrlAltFnтакі.

Як виняток для цього методу, зверніть увагу на такий (досить складний, але можливий) сценарій:

  • 1. - SSH в комп'ютер A (припустимо Linux).
  • 2. - Введіть новий screen -S AScrіз віддаленого терміналу на комп’ютері А.
  • 3. - SSH з AScrтерміналу GNU Screen на комп'ютер B.
  • 4. - Введіть новий screen -S BScrіз віддаленого терміналу на комп’ютері B.

Ви перебуваєте всередині a Screenна випадках 2 і 4, а зовні a Screenна випадках 1 і 3, але термінал буде блимати на випадках 2, 3 і 4.


1

Поки ssh'd потрапив у віддалену (стару) систему, я помітив, що $ TERM вказував, що я використовую 'screen-256color', однак для цього не було запису termcap / terminfo, тому я був змушений вдатися до наступного в .bashrc, щоб запобігати терміналу від випадкового сміття:

case $TERM in 
    (screen-256color) export TERM='screen'
esac

щоб отримати замість цього звичайний запис.

TL; DR, $ TERM, як правило, вказує, чи ви перебуваєте на екрані, коли ssh'd віддалено. Ви можете використовувати, case $TERM in (screen*) echo "you are in a screen session"; esacякщо ви просто хочете візуальну підказку і вам не потрібно робити щось конкретне


1

Додайте одне або кілька наступних файлів у свій .bashrc

  • alias mysession='echo ${STY}'
  • alias myterm='echo ${TERM}'
  • alias isscreen='if test -n "$STY"; then echo " screen session: ${STY}"; else echo " NOT a screen session"; fi'

Тоді ви зможете дізнатися, чи перебуваєте ви всередині screen, набравши прості команди.


1
Різновидом цього методу є додавання ${TERM}до вашого запиту $PS1. Це також можна зробити у вашому .bashrc. Наприклад, якщо для вашого параметра $PS1встановлено щось на зразок [\u@\h \W]\$, то ви можете змінити це чимось на зразокexport PS1="[\u@\h ${TERM} \W]\$"
Rhubbarb

Зараз я роблю щось подібне, крім дещо вигадливішого. :). Я додаю яскраве "S" в місці мого запиту, коли $ TERM == 'екран'. Робить тривіальним завжди знати, я в ній чи ні, без будь-якого набору тексту. Я залишаю методику як вправу для читача.
JJC

0

Проблема з більшістю із зазначених вище відповідей є те , що ми могли б бути в субоболочке з приєднаною сесії екрану. Або ми можемо відкривати оболонку для віддаленого хоста з сеансу екрану. У першому випадку ми можемо переглядати батьківське дерево процесу та відповідати screenназві програми. В останньому випадку, більшу частину часу ми можемо перевірити TERMзмінну на щось подібне screen*.

Моя відповідь схожа на / u / Parthian-Shot, але не настільки залежить від утиліти pstree; варіанти, якими він користується, мені недоступні. З іншого боку, моя реалізація все ще залежить від Linux: для систем, які не є Linux, потрібно налаштувати psкоманду; для систем зі старими оболонками, які не підтримують масиви, у вас буде ще більше робочих процедур. Але все ж таки:

ps_walk_parents() {
  local tmp
  local ppid=$PPID
  while [[ $ppid != 1 ]]; do
    tmp=($( ps -o ppid,comm -p $ppid ))
    ppid=${tmp[0]}  # grab parent pid
    echo ${tmp[1]}  # output corresponding command name
  done
}
if [[ "$TERM" =~ screen* ]] || ps_walk_parents |grep -qxi screen ; then
  # we are in a screen terminal 
fi

Ми могли б трохи оптимізувати нашу функцію, щоб зупинити пошук, якщо / коли батьківський процес відповідає імені цільової команди ("екран"), але загалом, функція буде вражати лише 2-3 ітерації. Імовірно, ви хочете помістити цей код в якусь ініціалізацію запуску, таку як .bashrc або .profile чи щось інше, тому знову ж таки, не варто оптимізувати.


наскільки я можу зрозуміти, ваш метод корисний, якщо ми знаходимося в підшарці вкладеного екранного сеансу, де $ TERM і $ STY не збереглися. Чи можете ви навести приклад того, як це відбуватиметься, бо що б я не намагався, $ TERM і $ STY завжди зберігалися.
ndemou

Вони зберігаються під час запуску , але не обов'язково, якщо ви перейдете до підшелупки (Спробуйте env -i bash). Або якщо ваш підключений термінал насправді підключений до іншого хоста черезssh а змінна TERM перезаписана, наприклад, у bashrc інших хостів.
Отей

-3

screen -ls можу сказати вам.

Зовнішній екран:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Detached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.

Усередині екрана:

$ screen -ls
There are screens on:
        16954.pts-1.auds916     (Attached)
        242.pts-8.auds916       (Detached)
2 Sockets in /tmp/screens/S-glennj.

7
Не зовсім. Те, що екран прикріплений, не означає, що ви всередині нього. Він може так само бути прикріплений / відкритий з іншого терміналу.
андол
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.