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

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

Если я использую 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 в данном случае)?

25
задан 11 June 2014 в 04:11

7 ответов

Исходная версия

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

  1. Получите родителя текущего процесса оболочки. Переменная удара $$ 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 

Так, мы можем сделать это немного более сложным (существуют некоторые bashisms здесь, этот не портативен):

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"
}

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

29
ответ дан 11 June 2014 в 04:11

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

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

ИЛИ

ps -aux | grep `ps -p $ -o ppid=` | awk 'NR==1{print $NF}'
9
ответ дан 11 June 2014 в 04:11

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

$ 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
3
ответ дан 11 June 2014 в 04:11

Другой (не прекрасный) возможность:

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

, Но это не работает с lxterminal, потому что существует переменная среды $WINDOWID пуста...

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

2
ответ дан 11 June 2014 в 04:11
basename "$(cat "/proc/$PPID/comm")"

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

Протесты

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

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

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

11
ответ дан 11 June 2014 в 04:11

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

, Например, в ударе:

read -s -dc -p  

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

<час>

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

\E[>c' da;da=${da##

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

<час>

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

\E'[>};echo "${da//;/ }"

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

<час>

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

0
ответ дан 7 October 2019 в 17:38

Имя терминала может быть установлено в переменных вашей среды.

echo $TERM

Примеры:

$ echo $TERM
xterm
3
ответ дан 22 January 2020 в 09:21

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

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