Como identificar o terminal a partir de um script?

8

E não diga " $TERM " - é sempre xterm .

Como pode um script bash informar em qual terminal está sendo executado, especificamente se é iTerm, Terminal.app ou, na verdade, um xterm?

Eu pergunto porque reset não funciona fora da caixa no Terminal.app e no iTerm2. O iTerm2, no entanto, reconhece uma sequência de escape para fazer uma reinicialização de terminal ( \x1b]50;ClearScrollback\x07 ), e se eu pudesse detectá-lo, eu poderia substituir reset por um alias que faça a coisa certa. AFAICT, Terminal.app não possui uma sequência de reinicialização e as pessoas recorrem ao ridículo tom-hackery para hackear esse .

Meu objetivo final aqui é ter o reset funcionando da mesma forma, independentemente de eu estar trabalhando no OS X ou Linux, trabalhando local ou remotamente por meio do SSH. (Eu não quero ter que tentar lembrar qual, e é útil fazer reset && command-that-outputs-a-bunch e ter up-enter funcionar.) Terminal.app e iTerm estão jogando uma chave neste plano, não implementando reset corretamente.

Isso significa que simplesmente sobrescrevendo reset não é bem: se eu estou em uma máquina Linux, ele precisa saber se estou usando gnome-terminal ou iTerm para enviar a seqüência de escape correta. / p>

Existe alguma maneira (mesmo se eu precisar de um ioctl ) para perguntar ao terminal o que é realmente ?

¹Para os propósitos desta questão, a reinicialização deve limpar a tela, redefinir o cursor e limpar o buffer de rolagem.

    
por Thanatos 04.12.2013 / 19:12

3 respostas

10

Use $TERM_PROGRAM .

iTerm o define para iTerm.app e Terminal.app para Apple_Terminal .

    
por 04.12.2013 / 19:42
1

$TERM não tem nada a ver com o emulador de terminal atualmente em execução, é apenas o seu terminal padrão e pode ser configurado para qualquer coisa. Para obter o nome do emulador de terminal que você está executando, você pode usar ps para obter o PID do processo pai do seu shell atual.

NOTA: O seguinte falhará no OSX, mas deverá funcionar bem no Linux

O PID do seu processo de shell atual é $$ . A partir daí, você pode usar ps para mostrar uma árvore de processos e imprimir o PID do pai da sua sessão atual do shell:

ps -axjf | awk -v pid=$$ '($2==pid){print $1}'

Você pode então passar esse PID para ps e dizer para ele imprimir o nome do comando:

ps -o comm=  $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')

Isso vai truncar o nome, deve ser o suficiente para você descobrir, mas pode não ser bom para o script. Para obter o nome completo, você pode tentar

ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'

Isso é o que eu recebo no meu sistema usando alguns terminais diferentes:

  1. terminator

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/bin/x-terminal-emulator
    
  2. gnome-terminal

    $ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    /usr/lib/gnome-terminal/gnome-terminal-server
    
  3. xterm

    $ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | 
       awk '{print $NF}'
    xterm
    
por 04.12.2013 / 19:48
0

Aqui está uma maneira portátil de obter o nome ou o caminho do processo pai:

iTerm 2:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm

gnome-terminal no Ubuntu:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal

Terminal.app:

$ ps -p $(ps -p $$ -o ppid=) -o comm=
login

Observe que, se Terminal.app estiver configurado para abrir novos shells com o shell de login padrão, o processo pai do shell será login e não o terminal.

A coluna comm é o caminho completo do comando no OS X e o nome do comando é truncado para 15 caracteres na implementação do procps no Linux.

    
por 05.12.2013 / 00:34