Y no digas " $TERM
", siempre es xterm
.
¿Cómo puede un bash
script saber en qué terminal se está ejecutando, específicamente si es iTerm, Terminal.app o, en realidad, un xterm?
Lo pregunto porque reset
no funciona¹ de fábrica en Terminal.app e iTerm2. iTerm2, sin embargo, reconoce una secuencia de escape para realizar un reinicio del terminal ( \x1b]50;ClearScrollback\x07
), y si pudiera detectarla, podría anularla reset
con un alias que haga lo correcto. AFAICT, Terminal.app carece de una secuencia de reinicio yla gente recurre a ridículos tom-hackery para hackear eso.
Mi objetivo final aquí es que reset
funcione igual ya sea que esté trabajando en OS X o Linux, trabajando localmente o de forma remota a través de SSH. (No quiero tener que intentar recordar cuál, y es útil hacer reset && command-that-outputs-a-bunch
y tener trabajo previo). Terminal.app e iTerm están arruinando este plan al no implementarlo reset
correctamente.
Esto significa que simplemente anular reset
no es suficiente: si estoy en una máquina Linux, necesita saber si estoy usando gnome-terminal
iTerm para poder enviar la secuencia de escape correcta.
¿Hay alguna forma (incluso si necesito un ioctl
) de preguntarle al terminal quéen realidad¿es?
¹Para los propósitos de esta pregunta, restablecer debe borrar la pantalla, restablecer el cursor y borrar el búfer de desplazamiento hacia atrás.
Respuesta1
Usar $TERM_PROGRAM
.
iTerm lo configura en iTerm.app
y Terminal.app en Apple_Terminal
.
Respuesta2
$TERM
no tiene nada que ver con el emulador de terminal que se está ejecutando actualmente, es solo su terminal predeterminado y se puede configurar para cualquier cosa. Para obtener el nombre del emulador de terminal que está ejecutando, puede utilizarlo ps
para obtener el PID del proceso principal de su shell actual.
NOTA: Lo siguiente fallará en OSX pero debería funcionar bien en Linux
El PID de su proceso de shell actual es $$
. Desde allí, puede usar ps
para mostrar un árbol de procesos e imprimir el PID del padre de su sesión de shell actual:
ps -axjf | awk -v pid=$$ '($2==pid){print $1}'
Luego puede pasar ese PID ps
y decirle que imprima el nombre del comando:
ps -o comm= $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}')
Eso truncará el nombre, debería ser suficiente para que usted lo descubra, pero puede que no sea bueno para las secuencias de comandos. Para obtener el nombre completo, puedes intentar
ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}'
Esto es lo que obtengo en mi sistema usando algunos terminales diferentes:
terminator
$ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' /usr/bin/x-terminal-emulator
gnome-terminal
$ ps --no-headers $(ps -axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' /usr/lib/gnome-terminal/gnome-terminal-server
xterm
$ ps --no-headers $(ps axjf | awk -v pid=$$ '($2==pid){print $1}') | awk '{print $NF}' xterm
Respuesta3
A continuación se muestra una forma portátil de obtener el nombre o la ruta del proceso principal:
iTérmino 2:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
/Applications/iTerm.app/Contents/MacOS/iTerm
gnome-terminal en Ubuntu:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
gnome-terminal
Terminal.aplicación:
$ ps -p $(ps -p $$ -o ppid=) -o comm=
login
Tenga en cuenta que si Terminal.app está configurado para abrir nuevos shells con el shell de inicio de sesión predeterminado, el proceso principal del shell es login
y no el terminal.
La comm
columna es la ruta completa del comando en OS X y el nombre del comando truncado a 15 caracteres en la implementación de procps en Linux.