Как я могу получить имя текущего терминала из командной строки?


25

Есть ли возможность получить тип терминала с помощью команды?

Если я использую gnome-terminal, вывод должен быть gnome-terminalили что-то подобное. Также было бы неплохо получить версию терминала.

Обновить

ps -aux | grep `ps -p $$ -o ppid=` 

выведет что-то вроде этого:

user     4239  0.0  0.7 292708 15744 pts/8    Sl   11:39   0:02 xfce4-terminal
user     4800  0.0  0.0   6176   820 pts/0    S+   12:23   0:00 grep --color=auto  4239

Это также будет работать с xterm, но как мне получить только имя ( xfce4-terminalв данном случае)?


Я только что обновил свой ответ с другим и лучшим подходом. Если у вас есть время, посмотрите и дайте мне знать, если это также работает для вас.
тердон

Спасибо, но первая проблема с rxvt -> window 31457282 has no pid associated with it(проверено на Lubuntu)
TuKsn

Ой? Блин, это странно. Я проверил под корицей.
тердон

Ответы:


29

Оригинальная версия

Один из способов сделать это - получить родительский процесс текущего сеанса оболочки и оттуда имя терминала.

  1. Получить родителя текущего процесса оболочки. Переменная bash $$- это PID вашей текущей оболочки, поэтому мы можем передать ее как запрос к ps(-p $$ ) и попросить tp напечатать PID родительского процесса ( -o ppid=конечный результат =состоит в том, чтобы избежать печати заголовков столбцов):

    $ ps -p $$ -o ppid=
    544
    

    Итак, PID родителя моей оболочки есть 544.

  2. Получить процесс, связанный с этим PID, и распечатать его командную строку

    $ ps -p 544 o args=
    /usr/bin/python /usr/bin/terminator
    

    Приведенный выше вывод будет зависеть от того, какой эмулятор терминала вы используете, я использую terminator.

  3. Объедините все в одной команде

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Используйте это, чтобы получить версию

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Добавьте небольшую функцию к вашему ~/.bashrc которая возвращает имя и версию используемого вами эмулятора терминала (это работает для большинства распространенных эмуляторов терминала):

    which_term(){
        term=$(ps -p $(ps -p $$ -o ppid=) -o args=);
        found=0;
        case $term in
            *gnome-terminal*)
                found=1
                echo "gnome-terminal " $(dpkg -l gnome-terminal | awk '/^ii/{print $3}')
                ;;
            *lxterminal*)
                found=1
                echo "lxterminal " $(dpkg -l lxterminal | awk '/^ii/{print $3}')
                ;;
            rxvt*)
                found=1
                echo "rxvt " $(dpkg -l rxvt | awk '/^ii/{print $3}')
                ;;
            ## Try and guess for any others
            *)
                for v in '-version' '--version' '-V' '-v'
                do
                    $term "$v" &>/dev/null && eval $term $v && found=1 && break
                done
                ;;
        esac
        ## If none of the version arguments worked, try and get the 
        ## package version
        [ $found -eq 0 ] && echo "$term " $(dpkg -l $term | awk '/^ii/{print $3}')    
    }

    Теперь вы можете получить имя терминала, а также передать любую понравившуюся вам опцию (например, --version .

Некоторые примеры использования разных терминалов:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, у этого нет ни одного -V, -versionили --versionфлагов, поэтому информация о версии не печатается.

    $  which_term
    rxvt  1:2.7.10-5
    
  4. gnome-terminal,

    $ which_term
    gnome-terminal  3.10.1-1
    
  5. konsole

    $ which_term
    Qt: 4.8.6
    KDE Development Platform: 4.11.3
    Konsole: 2.11.3
    
  6. lxterminal

    $ which_term
    lxterminal  0.1.11-4
    
  7. xfce4-terminal

    $ which_term
    xfce4-terminal 0.6.2 (Xfce 4.10)
    
    Copyright (c) 2003-2012
        The Xfce development team. All rights reserved.
    
    Written by Benedikt Meurer <benny@xfce.org>
    and Nick Schermer <nick@xfce.org>.
    
    Please report bugs to <http://bugzilla.xfce.org/>.
    

Новый и улучшенный

Вышеуказанный подход не заслуживает доверия, хотя. Он захлебнется, когда вы запустите свою оболочку после suобращения к другому пользователю или когда ваш терминал привязан к чему-либо и другим различным случаям. Поскольку мы, очевидно, работаем здесь с программами X, лучшим способом может быть использование чего-то вроде xdotool(устанавливаемого вместе sudo apt-get install xdotool) для получения информации:

perl -lpe 's/\0/ /g' /proc/$(xdotool getwindowpid $(xdotool getactivewindow))/cmdline

Выше будет напечатана командная строка, используемая для запуска текущего активного окна. Поскольку ваш терминал, предположительно, будет активен, это команда, которую он покажет. Это означает, что для большинства эмуляторов терминалов можно смело предположить, что 1-е возвращенное поле является именем терминала:

$ which_term 
lxterminal 

Это означает, что получение версии тривиально. Например

$ dpkg -l $(which_term) | awk '/^ii/{print $3}'
0.1.11-4

Не так для gnome-terminal:

$ which_term 
/usr/lib/gnome-terminal/gnome-terminal-server 

или terminator:

$ which_term
/usr/bin/python /usr/bin/terminator 

Таким образом, мы можем сделать его немного более сложным (здесь есть некоторые ошибки, этот не переносимый):

which_term(){
    term=$(perl -lpe 's/\0/ /g' \
           /proc/$(xdotool getwindowpid $(xdotool getactivewindow))/cmdline)

    ## Enable extended globbing patterns
    shopt -s extglob
    case $term in
        ## If this terminal is a python or perl program,
        ## then the emulator's name is likely the second 
        ## part of it
        */python*|*/perl*    )
         term=$(basename "$(readlink -f $(echo "$term" | cut -d ' ' -f 2))")
         version=$(dpkg -l "$term" | awk '/^ii/{print $3}')
         ;;
        ## The special case of gnome-terminal
        *gnome-terminal-server* )
          term="gnome-terminal"
        ;;
        ## For other cases, just take the 1st
        ## field of $term
        * )
          term=${term/% */}
        ;;
     esac
     version=$(dpkg -l "$term" | awk '/^ii/{print $3}')
     echo "$term  $version"
}

Это работает для всех случаев, на которых я тестировал.


@ Xubu-Tur хм, я только пробовал запускать каждый терминал с другого терминала вручную, и он работал нормально. Я предполагаю, что меню вашей среды рабочего стола имеют другой путь или каким-то образом отличаются в том, как они запускают терминалы. Я мог бы дать вам кое-что лучше, если вы скажете мне, как именно вы их запустили и какую ошибку вы получили. Если вы запустили из меню, проверьте, какую команду выполняет пункт меню.
тердон

@ Xubu-Tur не добавляйте скриншот. Просто вставьте сообщение об ошибке в ваш вопрос. То же самое для любой команды, которую запускает пункт меню. Не ждите, что я вручную скопирую его с картинки!
тердон

2
Вы можете просто использовать, $PPIDчтобы получить PID родительского процесса.
nyuszika7h

@ nyuszika7h да, можно и +1 за это, но я бы предпочел нет. Я только что проверил, и он не доступен в kshили tcsh. Это очень хорошая идея для семьи Баш, хотя это гораздо проще, чем мой подход.
тердон

Это определенно доступно в ksh93и mksh.
nyuszika7h

8

Попробуй это,

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $11}'

ИЛИ

ps -aux | grep `ps -p $$ -o ppid=` | awk 'NR==1{print $NF}'

Первый не включается, rxvtа terminatorвторой не включается uxtermи gnome-terminal(печатается /usr/lib/gnome-terminal/gnome-terminal-server). Все они потерпят неудачу (как и мои), если вы используете сеанс su.
тердон

7
basename "$(cat "/proc/$PPID/comm")"

$PPIDPID родительского процесса оболочки. commозначает команду . Это может быть или не быть полный путь, поэтому мы используем basenameего, если необходимо.

Предостережения

Это, вероятно, относится, по крайней мере, к некоторым другим ответам.

  • commтехнически argv[0], который на самом деле может быть произвольной строкой. Но в целом вы должны быть в состоянии положиться на это в данном конкретном случае.

  • Это не будет работать должным образом, если вы подключаетесь через SSH или используете его tmux, screenили что-то подобное.


Это очень приятно +1, но на терминальном терминаторе я получаю только terminвывод.
TuKsn

Я не знаю почему, возможно, это вина Терминатора.
nyuszika7h

Я думаю, это потому, что он работает как скрипт на python. Это действительно раздражает.
тердон

Обратите внимание, что $PPIDэто не является стандартным для всех оболочек. Например, tcshя получаю:PPID: Undefined variable.
Ариэльф

2

Вы можете попробовать следующую команду:

$ dpkg-query -W $COLORTERM
gnome-terminal  3.6.2-0ubuntu1

Обновление (спасибо OP и Avinash Raj):

$ dpkg-query -W $(ps -aux | grep "`ps -p $$ -o ppid=`" | awk 'NR==1{print $11}' | xargs basename)
rxvt    1:2.7.10-5

Я думаю, что он хочет знать это для активной терминальной сессии :) Так что, если он использует «замазку» в это время ...
Rinzwind

Не за "замазку", а как насчет xterm, с этой командой я получаю также gnome-terminal 3.6.2-0ubuntu1lв xterm?
TuKsn

2
Это не печатает терминал, который вы используете в данный момент. Он печатает все, что было установлено, по умолчанию $ COLORTERM, это не имеет никакого отношения к тому, что вы используете в данный момент.
тердон

Обновление также хорошо работает с xterm и показывает версию и имя.
TuKsn

Вся заслуга @Avinash и вас за правильную команду. Я только что добавил версию.
Сильвен Пино

2

Другая (не идеальная) возможность:

xprop -id $WINDOWID WM_CLASS | cut -d" " -f3 | sed 's/^.\(.*\)..$/\1/'

Но это не работает с lxterminal, потому что переменная окружения $WINDOWIDпуста ...

Терминатор показывает название «x-терминал-эмулятор».


0

Текущий терминал также может быть обнаружен с помощью escape-последовательности: Атрибуты устройства (вторичный DA)

Например, в bash:

read -s -dc -p $'\E[>c' da;da=${da##$'\E'[>};echo "${da//;/ }"

Это возвращает только какой-то идентификатор - и, к сожалению, я не знаю официального списка, который переводит их в настоящие имена.


Для реальной реализации, которая переводит некоторые известные идентификаторы в имена терминалов, см. Пример сценария bash: https://github.com/mintty/utils/blob/master/terminal.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.