Как проверить, какой эмулятор терминала сейчас используется?

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

15
задан 31 October 2012 в 22:34

9 ответов

Вы можете получить имя эмулятора терминала, изменив имя родительского процесса. Поэтому он работает с каждым эмулятором терминала.

В 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/^.* //')
0
ответ дан 31 October 2012 в 22:34

Попробуйте:

echo $TERM

Это более авторитетно, но может быть испорчено вашими программами. Однако, на моем, он говорит xterm, а на ttys - linux, что, я думаю, означает Linux Console.

0
ответ дан 31 October 2012 в 22:34

Использование pstree и awk - самый простой способ:

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

Объяснение

  1. Отображение дерева процессов с pstree из $ ( процесс).
  2. Аргументы pstree:

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

  4. Наконец, '{ print $2 }' сообщает awk выводить только 2-й шаблон соответствия (в данном случае, имя эмулятора терминала).
0
ответ дан 31 October 2012 в 22:34

Если вы используете bash, я думаю, эта команда поможет вам:

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

0
ответ дан 31 October 2012 в 22:34

Во многих системах linux echo $TERM return xterm см. Выше.

Чтобы задействовать фактический терминал, сделайте следующее:

1: Закройте каждый экземпляр терминала, работающий в данный момент.

2: Открыть новый терминал обычным способом.

3: введите команду следующим образом:

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

4: Возврат должен быть примерно таким:

lxterminal --geometry=135x20

Здесь is breakdown:

Итак: ps - это «состояние процесса»

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

Итак, (список ключевых слов) - 'cmd=' Только одно ключевое слово в списке. Итак, просто просим отобразить команду на открытие терминала.

ps option -p - это «по идентификатору процесса». Это очень хорошая опция для ps. Проблема в том, что вы должны передать ps этот идентификатор процесса. Итак, как получить идентификатор процесса? Мы разворачиваем выражение $(ps -o 'ppid=' -p $)

Здесь мы должны начать думать немного глубже. Я хотел бы изобрести этот bash однострочник, но я этого не сделал. Я думаю, что украл его из 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 снова «по идентификатору процесса», а в bash $ - идентификатор процесса.

Если вы вызываете ps -o 'ppid=' -p $ или любую другую команду, запрашивающую $ непосредственно из первой оболочки, он может сказать, что pid = 1, или pid из xWindow, или из вашей настольной программы, или вы можете получить реальный pid оболочки. Если вы спрашиваете много раз, вы, возможно, каждый раз получаете разные ответы!

Но, если вы вызовете дочь и спросите ее: «Кто ваш папа», она скажет вам! Очень умно. Хотел бы я быть таким гением, чтобы изобрести этот метод.

0
ответ дан 31 October 2012 в 22:34

Эта функция должна выполнять работу:

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
0
ответ дан 31 October 2012 в 22:34

Если вы использовали 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
}
0
ответ дан 31 October 2012 в 22:34

Вы правы, я только ответил на вопрос заголовка, а не вопрос в теле. Итак, поехали, Боб и твой дядя.

Я не уверен, в чем заключался переход случая, в одном ответе, показанном выше. Такой чехол переключения не нужен. Мой скрипт ~ / .bashrc - это всего лишь одна простая строка, все команды echo просто для удовольствия. Как объяснить ...

Любой термин при запуске читает ~ / .bashrc и выполняет все команды, которые он увидит в .bashrc. Таким образом, независимо от того, какой термин вызывается, он будет читать .bashrc и выполнять команды, поэтому единственной структурой, необходимой в .bashrc, будет изменение поведения или исключение того или иного термина. Желаемое поведение - чтобы каждый член выполнял одну и ту же команду, поэтому переключение регистра не требуется. Терминал сам скажет вам, как он был назван, поэтому нет необходимости различать.

Примечание (1) Я не проверял на guake, но работает для всех остальных, упомянутых в первом ответе jlliagre.

Примечание (2) Из-за форматирования в уценке для вики вы не можете вырезать и вставлять, как показано. Вы должны удалить каждый обратный удар , включая удаление символов подчеркивания, и добавить фактический обратный удар без пробела перед 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.

0
ответ дан 31 October 2012 в 22:34

Это решение находит родительский процесс запущенной оболочки, а затем ищет родительский процесс, который является эмулятором терминала:

pid=`ps -axo "pid,ppid,command" | grep $$ | head -n 1| awk '{print $2}'`; ps -axo "pid,ppid,command" | grep $pid | head -n 1 | awk '{$1=""; $2=""; print}'
0
ответ дан 4 April 2020 в 19:35

Другие вопросы по тегам:

Похожие вопросы: