Як я можу отримати ім'я поточного терміналу з командного рядка?


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

Вище буде надруковано командний рядок, який використовується для запуску активного вікна. Оскільки ваш термінал, імовірно, буде активним, це команда, яку він покаже. Це означає, що для більшості термінальних емуляторів ви можете сміливо припускати, що перше повернене поле є ім'ям терміналу:

$ 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 хм, я лише спробував, запустивши кожен термінал з іншого терміналу вручну, і він працював чудово. Я здогадуюсь, що у меню вашого робочого столу є інший шлях або якимось чином відрізняються тим, як вони запускають термінали. Я міг би дати вам щось краще, якщо ви точно скажете, як ви їх запустили і яку помилку ви отримали. Якщо ви запустили з меню, перевірте, яку команду виконує пункт меню.
terdon

@ 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). Усі вони вийдуть з ладу (як і у мене), якщо ви використовуєте су-сесію.
terdon

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

$PPIDPID батьківського процесу оболонки. commозначає командування . Це може бути або не бути повним шляхом, тому ми використовуємо basenameдля того, щоб прокреслити шлях.

Коваджі

Вони, ймовірно, стосуються і принаймні деяких відповідей.

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

  • Це не буде працювати , як і очікувалося , якщо ви підключаєтеся через SSH або використовувати tmux, screenабо що - щось подібне.


Це дуже приємно +1, але на терміналі термінатора я отримую лише terminвихід.
TuKsn

Я не знаю чому, це, мабуть, вина Термінатора.
nyuszika7h

Це тому, що він запускається як пітон сценарій. Це дійсно дратує.
тердон

Зверніть увагу, що $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, а ви за правильну команду. Я щойно додав версію.
Sylvain Pineau

2

Ще одна (не ідеальна) можливість:

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

Але це не працює з lxterminal, оскільки там змінна середовища $WINDOWIDпорожня ...

Термінатор показує назву "x-terminal-emulator".


0

Поточний термінал також може бути виявлений за допомогою послідовності виходу: Атрибути пристрою (вторинна DA)

Наприклад в bash:

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

Це повертає лише якийсь ідентифікатор - і, на жаль, я не знаю офіційного списку, який переводить їх на фактичні назви.


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

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