Як перевірити, який емулятор терміналу зараз використовується?


15

У мене встановлений gnome-термінал і Guake. Я хочу дати різні повідомлення про запуск, які відображатимуться на цих емуляторах терміналів під час їх запуску. Який код я повинен написати в .bashrc, щоб це було досягнуто?

Відповіді:


10

Ця функція повинна виконувати роботу:

container() {
    pid=$$
    while true; do
        pid=$(ps -h -o ppid -p $pid 2>/dev/null)
        case $(ps -h -o comm -p $pid 2>/dev/null) in
        (gnome-terminal) echo "Running in gnome terminal";return;;
        (xterm) echo "Running in xterm";return;;
        (rxvt) echo "Running in rxvt";return;;
        (python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
        esac
        [[ $(echo $pid) == 1 ]] && break
    done
}
container

Гарна відповідь! Не забудьте насправді викликати функцію за допомогою containerпісля визначення.
rosch

Я очікував, що це буде очевидно, але ви праві, відповідь відповідно оновлений.
jlliagre

@jlliagre Я спробував код. Він працює безперебійно на gnome-терміналі, але у Guake це проблеми. Це не дає жодного результату. Замість цього він замерзає, як ніби в глухому куті. Я повинен Ctrl + C це використовувати. Дійсно не зрозумів код, тому не знайте, куди йде не так.
VedVals

Код виправлено. Я пропустив guake, керований python, і помилка перешкоджала виходу функції. Дякуємо за відгук.
jlliagre

Вибачте чувак, все ще не зовсім працює. Помилка bash: [: too many arguments. Отримав bash v4.2.24, python v2.7.3, якщо це допомагає.
VedVals

10

Спробуйте це:

echo $TERM

Це більш авторитетно, але може зіпсувати ваші програми. Однак на моєму, він говорить xtermі на ttys він говорить linux, що, на мою думку, означає Linux Console.


2
$TERM- це змінна, яка посилається на специфікацію як на самовідповідь емулятора терміналу, який ви використовуєте, а не на власне сам емулятор. Наприклад, у моїй системі echo $TERMповертається, xtermхоча я фактично працюю lxterminal. Що відбувається - це xxterm відповідність lxterminal самозвітів. lxterminal насправді не повністю сумісний з xterm, тому ви повинні стежити. Файли специфікацій зазвичай розташовані в /usr/share/terminfo.
стажер

7

Ви можете отримати ім'я емулятора терміналу, ввівши ім'я батьківського процесу. Тому він працює з кожним емулятором терміналу.

In bash, zsh тощо:

basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

З рибною шкаралупою:

basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

Однак зауважте, що це вловлює аргументи програми, коли емулятор терміналу запускається з ними.
Robobenklein

Чи працює це, якщо я підключений за допомогою SSH?
користувач3731622

@ user3731622 це не буде! Вам доведеться переслати його від клієнта.
Енріко

2

У багатьох системах echo $TERMповернення Linux xtermдив. Стаджер пост вище.

Щоб отримати фактичний термінал у використанні, зробіть це:

1: Закрийте кожен запущений екземпляр терміналу.

2: Відкрийте новий термінал, використовуючи звичайний метод.

3: Введіть команду наступним чином:

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

4: Повернення має бути чимось таким:

lxterminal --geometry=135x20

Ось розбивка:

Отже: psце "статус процесу"

опція ps -o- Відображення інформації, пов’язаної зі списком вказаних пробілом або комою ключових слів. Звучить складно, але насправді це не так. (пробіл або кома), розділені (список ключових слів).

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

опція ps -p- "за методом ідентифікатора". О, це дуже приємний варіант для PS. Проблема в тому, що ви повинні передати в ps цей ідентифікатор процесу. Отже, як отримати ідентифікатор процесу? Ми розгортаємо вираз $(ps -o 'ppid=' -p $$)

Тут треба почати думати трохи глибше. Мені б хотілося, щоб я винайшов цей однотонний баш, але цього не зробив. Я думаю, що я його вкрав з https://wiki.archlinux.org/ десь, я не міг знову знайти. Ці хлопці приголомшливі, але багато разів я не можу зрозуміти, що вони кажуть робити до довгого навчання. Що ми можемо зробити - це зрозуміти зараз, бо я поясню.

тому ми знаємо, що $це оператор розширення в bash. Мені подобається думати "розмотати". Отже, $(foo -opt bar)буде розгортати або розширювати "foo -opt bar". Але в bash, одна кругла дужка (...)відкриває нижню частину корпусу.

Отже, $(foo -opt bar)розгортається "foo -opt bar" під час запуску в дочірній оболонці . Дуже дивно і важко зрозуміти.

Гаразд, тому ми знову запускаємо майже ідентичну команду, ps -o 'ppid=' -p $$але цього разу ps, статус процесу, показує нам, що він може бачити в екземплярі дочірньої оболонки .

-oсписок ключових слів, лише одне ключове слово, як і раніше, але ppid=це запитання безпосередньо для ідентифікатора процесу батьківської оболонки !! З ВІЧНОГО ДНЕГО ШЕЛА! Дуже розумно, так? Я так схвильований, коли можу це зрозуміти!

-pзнову "id id процесу", а в bash $$- ідентифікатор процесу.

Якщо ви телефонуєте ps -o 'ppid=' -p $$або будь-яка інша команда, яка запитує $$безпосередньо з першої оболонки, він може сказати, що pid = 1, або pid з xWindow, або з вашої настільної програми, або ви, можливо, отримаєте фактичний pid shell. Якщо ви запитуєте багато разів, то, можливо, кожен раз отримуєте різні відповіді!

Але, якщо ви позовете дочку і запитаєте її "Хто твій тато", вона скаже тобі! Дуже розумний. Я б хотів, щоб я міг бути таким генієм, щоб винайти цей метод.


Гаразд, тому АС не дозволить належної розбивки в межах однієї посади. Вибачте, не бажаю боротися з системою блогу та створювати кілька публікацій. Можливо, ви можете отримати ідею.
стажер

Ваша інша відповідь, здається, є складним та інформативним коментарем до цієї відповіді, а не відповіддю на питання ... Було б чудово, якби ви могли поєднати дві відповіді в одну та видалити одну з них, і додати її, щоб вона повністю відповідає на питання. Використовуйте ----, щоб намалювати лінію посередині? Також є кнопка.
Занна

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

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

Спасибі за вашу відповідь. Мені шкода, можливо, я наскочив на тебе. Я дуже вибачаюся.
стаж

1

Використання pstreeта awkнайпростіший спосіб:

pstree -sA $$ | awk -F "---" '{ print $2 }'

Пояснення

  1. Відображення дерева процесів з pstreeз $$(atual процесу).
  2. В pstreeаргументах:

    • -s: відображення батьків процесу
    • -A: відображення виводу в чистому ASCII.
  3. awkІнструмент сканування шаблону і -Fаргумент використовується для поділу процесів.

  4. Нарешті, '{ print $2 }'повідомляє awkвиводити лише другий шаблон відповідності (у цьому випадку ім'я емулятора терміналу).

Ви впевнені $2? У моєму випадку те, що вкладається, awk- це насправді systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
Енріко Марія Де Анджеліс

@EnricoMariaDeAngelis Ya. Дякую за ваше спостереження. У моєму випадку емулятор терміналу ініціалізується безпосередньо в системній службі. Я ще раз перевіряю код і редагую його з виправленням.
silvadev

Це не працює, коли я використовую комбінацію клавіш для запуску емулятора. На XFCE я отримую xfsettingsdзамість терміналу, який я використовую.
Майкл Гофман

Працює краще, якщо ви почнете з кінця:pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
Лефаф

0

Ви маєте рацію, я відповідав лише на заголовкове запитання, а не на тіло. Тож ось ти і дядько Боба.

Я не впевнений, в чому справа перемикача, в одній відповіді, показаній вище. Такий вимикач корпусу не потрібен. Мій сценарій ~ / .bashrc - це лише один простий рядок, усі команди ехо просто для розваги. Як пояснити ...

Будь-який термін при запуску читає ~ / .bashrc і виконує всі команди, які він побачить у .bashrc. Отже, незалежно від того, який термін називається, він буде читати .bashrc і виконувати команди, тому лише структура, потрібна в .bashrc, могла б змінити поведінку або виключити той чи інший термін. Бажана поведінка полягає в тому, щоб кожен термін виконував одну і ту ж команду, тому перемикання випадку не потрібно. Сам Термінал розповість, як його називали, тому розрізняти не потрібно.

Примітка (1) Я не тестував на guake, але працює для всіх інших, про які йшлося у першій відповіді jlliagre.

Примітка (2) Через форматування у відмітці для wiki, ви не можете вирізати та вставити, як показано. Ви повинні видалити кожні зворотні одиничні лапки , в тому числі для видалення знаків підкреслення, і додати фактичні зворотний одиничні лапки, без пробілу до psабо після -p $$).

сценарій для ~ / .bashrc

# show welcome message for actual terminal in use
echo "Welcome.  You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."

Це було дуже весело. Я додав це до власного ~ / .bashrc.


за ноту (1), пройшли тест на Tilda, працює чудово. Гуаке схожий на Тільду, але написаний пітоном, тому досі не знаю про Гуаке.
стажер

0

якщо ви використовуєте bash, я вважаю, що ця команда допоможе вам:

which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))


0

Якщо ви використовували ZSH, є краще (швидше) рішення, яке використовує лише вбудовані ZSH та маніпулює /proc/$pid/{stat,cmdline}безпосередньо.

get-terminal-emulator() {
    if [[ $TTY = "/dev/tty"* ]]; then
        echo "linux-console"
        return
    fi
    local pid=$$ name=''
    while true; do
        proc_stat=(${(@f)$(</proc/${pid}/stat)})
        name=${proc_stat[2]//[()]/}
        case "${name}" in
            gnome-terminal|konsole|rxvt|xterm)
                echo "${name}"; return ;;
            python*)
                local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
                if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
                    echo "guake"; return
                fi
                ;;
        esac
        if test "$pid" = "1" -o "$pid" = ""; then
            echo "unknown"
            return
        fi
        pid=${proc_stat[4]}       
    done
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.