¿Cómo puedo obtener el nombre del terminal actual de la línea de comandos?


25

¿Existe la posibilidad de obtener el tipo de terminal con un comando?

Si estoy usando gnome-terminal, la salida debería ser gnome-terminalo algo similar. También sería bueno obtener la versión del terminal.

Actualizar

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

generará algo como esto:

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

Esto también funcionará con xterm, pero ¿cómo obtengo solo el nombre ( xfce4-terminalen este caso)?


Acabo de actualizar mi respuesta con un enfoque diferente y mejor. Si tienes tiempo, échale un vistazo y avísame si también te funciona.
terdon

Gracias pero primer problema con rxvt -> window 31457282 has no pid associated with it(probado en Lubuntu)
TuKsn

¿Oh? Maldición, eso es raro. Lo probé con canela.
terdon

Respuestas:


29

Versión original

Una forma de hacerlo es obtener el proceso principal de su sesión de shell actual y, a partir de ahí, el nombre del terminal.

  1. Obtenga el padre del proceso de shell actual. La variable bash $$es el PID de su shell actual, por lo que podemos darle eso como una consulta a ps( -p $$) y pedirle que imprima el PID del proceso padre ( -o ppid=el final =es evitar imprimir encabezados de columna):

    $ ps -p $$ -o ppid=
    544
    

    Entonces, el PID del padre de mi shell es 544.

  2. Obtenga el proceso asociado con ese PID e imprima su línea de comando

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

    El resultado anterior dependerá de qué emulador de terminal esté usando, estoy usando terminator.

  3. Combina todo en un solo comando

    ps -p $(ps -p $$ -o ppid=) o args=
    
  4. Use eso para obtener la versión

    $(ps -p $(ps -p $$ -o ppid=) o args=) --version
    terminator 0.97
    
  5. Agregue una pequeña función a su ~/.bashrcque devuelva el nombre y la versión del emulador de terminal que está utilizando (esto funciona para los emuladores de terminal más comunes):

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

    Ahora puede obtener el nombre del terminal y también pasarle cualquier opción que desee (como --version.

Algunos ejemplos con diferentes terminales:

  1. xterm

    $ which_term
    XTerm(297)
    
  2. terminator

    $ which_term 
    terminator 0.97
    
  3. rxvt, Éste tiene ninguno de los -V, -versiono --versionbanderas por lo que no se imprime información de la versión.

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

Nuevo y mejorado

Sin embargo, el enfoque anterior no es tan confiable. Se ahogará cuando ejecute su shell después de suacceder a otro usuario o cuando su terminal tenga un alias para algo y otros casos. Como obviamente estamos trabajando con programas X aquí, una mejor manera podría ser usar algo como xdotool(instalable con sudo apt-get install xdotool) para obtener la información:

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

Lo anterior imprimirá la línea de comando utilizada para iniciar la ventana actualmente activa. Dado que su terminal, presumiblemente, estará activo, ese es el comando que mostrará. Esto significa que para la mayoría de los emuladores de terminal, puede asumir con seguridad que el primer campo devuelto es el nombre del terminal:

$ which_term 
lxterminal 

Esto significa que obtener la versión es trivial. Por ejemplo

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

No es así para gnome-terminal:

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

o terminator:

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

Entonces, podemos hacerlo un poco más complejo (hay algunos bashismos aquí, este no es 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"
}

Esto funciona para todos los casos que probé.


@ Xubu-Tur hmm, solo lo intenté iniciando cada terminal desde otra terminal manualmente y funcionó bien. Supongo que los menús de su entorno de escritorio tienen una ruta diferente o de alguna manera difieren en la forma en que lanzan los terminales. Podría darte algo mejor si me dices exactamente cómo los lanzaste y qué error obtuviste. Si inició desde un menú, verifique qué comando ejecuta el elemento del menú.
terdon

@ Xubu-Tur no agrega una captura de pantalla. Simplemente pegue el mensaje de error en su pregunta. Lo mismo para cualquier comando que inicie el elemento del menú. ¡No esperes que lo copie manualmente de una imagen!
terdon

2
Simplemente puede usar $PPIDpara obtener el PID del proceso padre.
nyuszika7h

@ nyuszika7h sí, puedes y +1 por eso, pero prefiero no hacerlo. Acabo de comprobar y no está disponible en ksho tcsh. Sin embargo, es una muy buena idea para la familia bash, ya que es mucho más simple que mi enfoque.
terdon

Definitivamente está disponible en ksh93y mksh.
nyuszika7h

8

Prueba esto,

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

O

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

La primera falla en rxvty terminatory la segunda falla en uxtermy gnome-terminal(lo imprime /usr/lib/gnome-terminal/gnome-terminal-server). Todos fallarán (al igual que los míos) si está utilizando una sesión su.
terdon

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

$PPIDes el PID del proceso padre del shell. commsignifica comando . Puede o no ser una ruta completa, por lo que usamos basenamepara eliminar la ruta si es necesario.

Advertencias

Probablemente, esto también se aplica al menos a algunas de las otras respuestas.

  • commes técnicamente argv[0], lo que en realidad puede ser una cadena arbitraria. Pero, en general, debería poder confiar en él para este caso en particular.

  • Esto no funcionará como se espera si se conecta a través de SSH o usa tmux, screeno algo similar.


Esto es muy agradable +1, pero en el terminal terminador solo obtengo termincomo salida.
TuKsn

No sé por qué, probablemente sea culpa de Terminator.
nyuszika7h

Es porque se ejecuta como un script de Python, creo. Es muy molesto.
terdon

Tenga en cuenta que $PPIDno es estándar en todos los depósitos. por ejemplo, en tcshobtengo:PPID: Undefined variable.
arielf

2

Puedes probar el siguiente comando:

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

Actualización (gracias a OP y 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

Creo que quiere saberlo para la sesión de terminal activa :) Entonces, si está usando "masilla" en ese momento ...
Rinzwind

No, no sobre "masilla", pero ¿qué pasa con xterm, con este comando también obtengo gnome-terminal 3.6.2-0ubuntu1len xterm?
TuKsn

2
Esto no imprime el terminal que está utilizando en este momento. Imprime lo que se haya configurado en el $ COLORTERM predeterminado, que no tiene nada que ver con lo que está utilizando en ese momento.
terdon

La actualización funciona bien también con xterm y muestra la versión y el nombre.
TuKsn

Todo el crédito va a @Avinash y a ti por el comando correcto. Acabo de agregar la versión.
Sylvain Pineau

2

Otra posibilidad (no perfecta) es:

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

Pero esto no funciona con lxterminal porque hay una variable de entorno $WINDOWIDvacía ...

Terminator muestra el nombre "x-terminal-emulator".


0

El terminal actual también se puede detectar a través de una secuencia de escape: los atributos del dispositivo (DA secundaria)

Por ejemplo en bash:

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

Esto devuelve solo algún tipo de identificación, y lamentablemente no conozco una lista oficial que los traduzca a los nombres reales.


Para una implementación real, que traduce algunos identificadores conocidos a nombres de terminales, vea este script bash de ejemplo: https://github.com/mintty/utils/blob/master/terminal

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.