Como posso obter o nome do terminal atual na linha de comando?


25

Existe a possibilidade de obter o tipo de terminal com um comando?

Se eu estiver usando gnome-terminal, a saída deve ser gnome-terminalou algo semelhante. Também seria bom obter a versão do terminal.

Atualizar

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

irá produzir algo como isto:

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

Isso também funcionará com o xterm, mas como obtenho apenas o nome ( xfce4-terminalneste caso)?


Acabei de atualizar minha resposta com uma abordagem diferente e melhor. Se você tiver tempo, dê uma olhada e deixe-me saber se também funciona para você.
terdon

Obrigado, mas primeiro problema com rxvt -> window 31457282 has no pid associated with it(testado em Lubuntu)
TuKsn

Oh? Porra, isso é estranho. Eu testei com canela.
terdon

Respostas:


29

Versão original

Uma maneira de fazer isso é obter o processo pai da sua sessão atual do shell e, a partir daí, o nome do terminal.

  1. Obtenha o pai do processo atual do shell. A variável bash $$é o PID do seu shell atual; portanto, podemos fornecer isso como uma consulta para ps( -p $$) e solicitar que ele imprima o PID do processo pai ( -o ppid=a seguir =é para evitar a impressão de cabeçalhos de coluna):

    $ ps -p $$ -o ppid=
    544
    

    Portanto, o PID do pai do meu shell é 544.

  2. Obtenha o processo associado a esse PID e imprima sua linha de comando

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

    A saída acima dependerá do emulador de terminal que você estiver usando terminator.

  3. Combine tudo em um único comando

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Use isso para obter a versão

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Adicione uma pequena função ao seu ~/.bashrcque retorne o nome e a versão do emulador de terminal que você está usando (isso funciona para os emuladores de terminal mais comuns):

    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}')    
    }

    Agora você pode obter o nome do terminal e também passar qualquer opção que desejar (como --version.

Alguns exemplos usando diferentes terminais:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, Este tem nenhum dos -V, -versionou --versionbandeiras tão sem info versão está impresso.

    $  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/>.
    

Novo e melhorado

A abordagem acima não é tão confiável. Ele engasga quando você executa o shell após suacessar outro usuário ou quando o terminal está alias a algo e vários outros casos. Como estamos obviamente trabalhando com programas X aqui, uma maneira melhor pode ser usar algo como xdotool(instalável com sudo apt-get install xdotool) para obter as informações:

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

O texto acima imprimirá a linha de comando usada para iniciar a janela ativa no momento. Como seu terminal, presumivelmente, estará ativo, esse é o comando que ele mostrará. Isso significa que, para a maioria dos emuladores de terminal, você pode assumir com segurança que o primeiro campo retornado é o nome do terminal:

$ which_term 
lxterminal 

Isso significa que obter a versão é trivial. Por exemplo

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

Não é assim para gnome-terminal:

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

ou terminator:

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

Portanto, podemos torná-lo um pouco mais complexo (existem alguns basismos aqui, este não é portátil):

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

Isso funciona para todos os casos em que testei.


@ Xubu-Tur hmm, tentei apenas iniciar cada terminal manualmente a partir de outro terminal e funcionou bem. Suponho que os menus do ambiente de área de trabalho tenham um caminho diferente ou que, de alguma forma, sejam diferentes na maneira como iniciam os terminais. Talvez eu possa lhe oferecer algo melhor se você me contar exatamente como os lançou e qual erro ocorreu. Se você iniciou a partir de um menu, verifique qual comando o item de menu executa.
terdon

@ Xubu-Tur não adiciona uma captura de tela. Basta colar a mensagem de erro na sua pergunta. O mesmo para qualquer comando iniciado pelo item de menu. Não espere que eu copie manualmente de uma foto!
terdon

2
Você pode usar apenas $PPIDpara obter o PID do processo pai.
precisa saber é o seguinte

@ nyuszika7h sim, você pode e +1 para isso, mas eu prefiro não. Acabei de verificar e não está disponível em kshou tcsh. É uma ideia muito boa para a família bash, já que é muito mais simples do que minha abordagem.
terdon

Definitivamente, está disponível em ksh93e mksh.
precisa saber é o seguinte

8

Tente isso,

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

OU

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

A primeira falha em rxvte terminatore a segunda falha em uxterme gnome-terminal(imprime /usr/lib/gnome-terminal/gnome-terminal-server). Todos eles falharão (como o meu) se você estiver usando uma sessão su.
terdon

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

$PPIDé o PID do processo pai do shell. commsignifica comando . Pode ou não ser um caminho completo, portanto, usamos o basenamestrip, se necessário.

Ressalvas

Provavelmente também se aplicam a pelo menos algumas das outras respostas.

  • commé tecnicamente argv[0], o que pode realmente ser uma sequência arbitrária. Mas, em geral, você deve poder confiar nisso para esse caso específico.

  • Isso não funcionará conforme o esperado se você se conectar através de SSH ou usar tmux, screenou algo semelhante.


Isso é muito bom +1, mas no terminal terminador recebo apenas termincomo saída.
TuKsn

Não sei por que, provavelmente é culpa do Terminator.
precisa saber é o seguinte

É porque é executado como um script python, eu acho. É realmente irritante.
terdon

Observe que isso $PPIDnão é padrão em todas as conchas. por exemplo, tcsheu recebo:PPID: Undefined variable.
arielf 6/06/2014

2

Você pode tentar o seguinte comando:

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

Atualização (graças ao OP e 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

Acho que ele quer conhecê-lo para a sessão de terminal ativa :) Então, se ele está usando "massa" naquele tempo ...
Rinzwind

Não, não sobre "massa de vidraceiro", mas o que é o xterm, com este comando eu também recebo o gnome-terminal 3.6.2-0ubuntu1lxterm?
precisa saber é o seguinte

2
Isso não imprime o terminal que você está usando no momento. Ele imprime o que foi definido como $ COLORTERM padrão, que não tem nada a ver com o que você está usando no momento.
terdon

A atualização também funciona bem com o xterm e mostra a versão e o nome.
TuKsn

Todo o crédito vai para @Avinash e você pelo comando certo. Acabei de adicionar a versão.
Sylvain Pineau

2

Outra possibilidade (não perfeita) é:

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

Mas isso não funciona com o lxterminal porque a variável de ambiente está $WINDOWIDvazia ...

O Terminator mostra o nome "x-terminal-emulator".


0

O terminal atual também pode ser detectado através de uma sequência de escape: The Device Attributes (Secondary DA)

Por exemplo no bash:

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

Isso retorna apenas algum tipo de identificação - e, infelizmente, não conheço uma lista oficial que as traduza para os nomes reais.


Para uma implementação real, que converta alguns IDs conhecidos em nomes de terminal, consulte este exemplo de script bash: https://github.com/mintty/utils/blob/master/terminal

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.