Como identificar o terminal a partir de um script?

Como identificar o terminal a partir de um script?

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

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

Eu pergunto porque resetnão funciona¹ imediatamente no Terminal.app e no iTerm2. O iTerm2, no entanto, reconhece uma sequência de escape para redefinir o terminal ( \x1b]50;ClearScrollback\x07) e, se eu pudesse detectá-la, poderia substituí-la resetpor um alias que fizesse a coisa certa. AFAICT, Terminal.app não possui uma sequência de redefinição eas pessoas recorrem a tom-hackers ridículos para contornar isso.

Meu objetivo final aqui é trabalhar resetda mesma forma, esteja eu trabalhando no OS X ou Linux, local ou remotamente por meio de SSH. (Não quero ter que tentar lembrar qual, e é útil fazer reset && command-that-outputs-a-bunche inserir o trabalho.) Terminal.app e iTerm estão atrapalhando esse plano por não implementarem resetcorretamente.

Isso significa que simplesmente substituir resetnão é bem isso: se estou em uma máquina Linux, ele precisa saber se estou usando gnome-terminalo iTerm para enviar a sequência de escape correta.

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

¹Para os fins desta pergunta, a redefinição deve limpar a tela, redefinir o cursor e limpar o buffer de rolagem.

Responder1

Usar $TERM_PROGRAM.

iTerm define como iTerm.appe Terminal.app como Apple_Terminal.

Responder2

$TERMnã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 pspara obter o PID do processo pai do seu shell atual.

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

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

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

Você pode então passar esse PID pse solicitar que ele imprima o nome do comando:

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

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

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

Isto é o que 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
    

Responder3

Esta é uma maneira portátil de obter o nome ou caminho do processo pai:

iTermo 2:

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

terminal gnome 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á logine não o terminal.

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

informação relacionada