¿Cómo verificar qué emulador de terminal se está utilizando actualmente?


15

Tengo gnome-terminal y Guake instalados. Quiero dar diferentes mensajes de inicio para que se muestren en estos emuladores de terminal a medida que comienzan. ¿Qué código debo escribir en .bashrc para que esto se logre?

Respuestas:


10

Esta función debería hacer el trabajo:

container() {
    pid=$$
    while true; do
        pid=$(ps -h -o ppid -p $pid 2>/dev/null)
        case $(ps -h -o comm -p $pid 2>/dev/null) in
        (gnome-terminal) echo "Running in gnome terminal";return;;
        (xterm) echo "Running in xterm";return;;
        (rxvt) echo "Running in rxvt";return;;
        (python) if [ ! -z "$(ps -h -o args -p $pid 2>/dev/null | grep guake)" ]; then echo "Running in Guake"; return; fi ;;
        esac
        [[ $(echo $pid) == 1 ]] && break
    done
}
container

¡Buena respuesta! No olvide llamar realmente a la función con containerdespués de la definición.
rosch

Esperaba que esto fuera obvio pero tienes razón, la respuesta se actualiza en consecuencia.
jlliagre

@jlliagre Probé el código. Funciona sin problemas en gnome-terminal pero tiene un problema en Guake. No da ningún resultado. En cambio, se congela como si estuviera en un punto muerto. Tengo que Ctrl + C para usarlo. Realmente no entendí el código, así que no sé dónde va mal.
VedVals

Código fijo Perdí guake es ejecutado por python y tuve un error que impedía que la función saliera. Gracias por la respuesta.
jlliagre 01 de

Lo siento amigo, todavía no funciona del todo. Da error bash: [: too many arguments. Tengo bash v4.2.24, python v2.7.3 si ayuda.
VedVals

10

Prueba esto:

echo $TERM

Esto es más autoritario, pero sus programas podrían estropearlo. Sin embargo, en el mío, dice xtermy en ttys dice linux, lo que creo que significa Consola Linux.


2
$TERMes una variable que se refiere a la especificación autoinformada por el emulador de terminal que está utilizando, no al emulador en sí. Por ejemplo, en mi sistema, echo $TERMregresa xtermaunque realmente estoy ejecutando lxterminal. Lo que está sucediendo es lxterminal autoinformes de cumplimiento xterm. lxterminal en realidad no es totalmente compatible con xterm, por lo que debe tener cuidado. Los archivos de especificaciones generalmente se encuentran en /usr/share/terminfo.
stazher

7

Puede obtener el nombre del emulador de terminal, seleccionando el nombre del proceso principal. Por lo tanto, funciona con todos los emuladores de terminal.

En bash, zsh, etc .:

basename "/"$(ps -f -p $(cat /proc/$(echo $$)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

Con concha de pescado:

basename "/"(ps -f -p (cat /proc/(echo %self)/stat | cut -d \  -f 4) | tail -1 | sed 's/^.* //')

Sin embargo, tenga en cuenta que esto detectará los argumentos del programa cuando se inicie el emulador de terminal con ellos.
Robobenklein

¿Funciona esto si estoy conectado usando SSH?
user3731622

@ user3731622 no lo hará! Tendrás que reenviarlo desde el cliente.
Enrico

2

En muchos sistemas Linux echo $TERMregresarxterm ver post stazher anteriormente.

Para obtener el terminal real en uso, haga esto:

1: cierre cada instancia de terminal que se esté ejecutando actualmente.

2: Abra una nueva terminal utilizando su método habitual.

3: Ingrese el comando de la siguiente manera:

ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)

4: El retorno debería ser algo así:

lxterminal --geometry=135x20

Aquí está el desglose:

Entonces: pses "estado del proceso"

La opción ps -oes Mostrar información asociada con el espacio o la lista separada por comas de palabras clave especificadas. Suena complicado, pero en realidad no lo es. (espacio o coma) separados (lista de palabras clave) especificados.

Entonces, (lista de palabras clave) es 'cmd='Solo una palabra clave en la lista. Entonces, solo pido mostrar el comando para abrir la terminal.

La opción ps -pes "por id de proceso" Wow, esta es una muy buena opción para ps. El problema es que debes pasar a ps este id de proceso. Entonces, ¿cómo obtener la identificación del proceso? Desenvolvemos la expresión $(ps -o 'ppid=' -p $$)

Aquí debemos comenzar a pensar un poco más profundo. Desearía haber inventado este bash one-liner, pero no lo hice. Creo que lo robé de https://wiki.archlinux.org/ en algún lugar, no pude encontrarlo de nuevo. Esos tipos son increíbles, pero muchas veces no puedo entender lo que dicen hacer hasta después de mucho estudio. Lo que podemos hacer es entenderlo ahora, porque lo explicaré.

entonces sabemos que $es operador de expansión en bash. Me gusta pensar "desenvolver". Por lo tanto, $(foo -opt bar)se desenvolverá o expandirá, "foo -opt bar". Pero en bash, una sola llave redonda (...)abre la subshell.

Por lo tanto, $(foo -opt bar)expande la "barra foo-opt" como se ejecuta en el shell de la hija . Muy raro y difícil de entender.

Bien, ahora estamos ejecutando un comando casi idéntico nuevamente, ps -o 'ppid=' -p $$pero esta vez ps, estado del proceso, nos muestra lo que puede ver desde la instancia de shell hija .

-olista de palabras clave, solo una palabra clave como antes, ¡pero ppid=esto está pidiendo directamente la identificación del proceso del shell principal! De DENTRO DE LA HIJA SHELL! Muy inteligente, si? ¡Estoy tan emocionado cuando puedo entender esto!

-pde nuevo, "por id de proceso" y en bash $$es el id de proceso.

Si llama ps -o 'ppid=' -p $$, o cualquier otro comando que solicite $$directamente desde el primer shell, podría decir pid = 1, o pid desde xWindow, o desde su programa de escritorio, o tal vez obtenga un pid real de shell. Si preguntas muchas veces, ¡quizás obtengas respuestas diferentes cada vez!

Pero, si invocas a una hija y le preguntas "¿Quién es tu papá", ella te lo dirá! Muy inteligente. Ojalá pudiera ser tan genial para inventar este método.


OK, por lo que AU no permitirá un desglose adecuado en una publicación. Lo sentimos, no estoy dispuesto a pelear con el sistema de blogs y hacer múltiples publicaciones. Quizás puedas hacerte una idea.
stazher

Su otra respuesta parece ser un comentario sofisticado e informativo sobre esta respuesta en lugar de una respuesta a la pregunta ... Sería genial si pudiera combinar sus dos respuestas en una y eliminar una de ellas, y agregarla para que Responde completamente la pregunta. Use ---- para dibujar una línea en el medio? También hay un botón.
Zanna

Creo que he respondido a la pregunta OP exactamente y en detalle. Saltaste sobre mí antes de que tuviera la oportunidad de entender el sistema de edición de blogs y terminar. Trae los votos negativos, estoy acostumbrado.
stazher

1
No creo que haya saltado sobre ti, solo estaba haciendo una revisión ... gracias por hacer tu publicación más completa
Zanna

Gracias por su respuesta. Lo siento, tal vez salté sobre ti. Me disculpo mucho
stazher

1

Usar pstreey awkes la forma más fácil:

pstree -sA $$ | awk -F "---" '{ print $2 }'

Explicando

  1. Muestra un árbol de procesos con pstreeof $$(el proceso actual).
  2. Los pstreeargumentos:

    • -s: mostrar los padres de un proceso
    • -A: muestra la salida en ASCII puro.
  3. La awkherramienta escanea un patrón y un -Fargumento se utiliza para dividir los procesos.

  4. Finalmente '{ print $2 }'le dice a awkgenerar solo el segundo patrón de coincidencia (en este caso, el nombre del emulador de terminal).

¿Estás seguro $2? En mi caso, lo que se canaliza es en awkrealidad systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree...
Enrico Maria De Angelis

@EnricoMariaDeAngelis Ya. Gracias por tu observación En mi caso, el emulador de terminal se inicializa directamente en el servicio systemd. Reviso nuevamente el código y lo edito con una corrección.
silvadev

Esto no funciona cuando uso un atajo de teclado para iniciar el emulador. En XFCE, obtengo en xfsettingsdlugar del terminal que estoy usando.
Michael Hoffmann

Funciona mejor si comienzas desde el final:pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
lleaff

0

Tienes razón, solo respondí la pregunta del titular, no la pregunta en el cuerpo. Así que aquí tienes, y el tío de Bob.

No estoy seguro de qué se trataba el cambio de caso, en una respuesta que se muestra arriba. Tal cambio de caso no es necesario. Mi script ~ / .bashrc es en realidad solo una línea simple, todos los comandos echo son solo por diversión. Cómo explicar...

Cualquier término al comenzar lee ~ / .bashrc y ejecuta los comandos que verá en .bashrc. Entonces, no importa qué término se llame, leerá .bashrc y ejecutará los comandos, por lo que solo la estructura necesaria en .bashrc sería modificar el comportamiento o excluir un término u otro. El comportamiento deseado es que cada término ejecute el mismo comando, por lo que no es necesario cambiar el caso. El propio terminal le dirá cómo fue llamado, por lo que no hay necesidad de diferenciar.

Nota (1) No probé guake, pero funciona para todos los demás mencionados en la primera respuesta de jlliagre.

Nota (2) Debido al formato en markdown para wiki, no puede cortar y pegar como se muestra. Debe eliminar cada marca de retroceso , incluso eliminar los caracteres subrayados, y agregar la marca de fondo real, sin espacio antes pso después del -p $$).

script para ~ / .bashrc

# show welcome message for actual terminal in use
echo "Welcome.  You are attempting to use"
echo ""
echo _backtick_ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$)_backtick_
echo ""
echo "Good Luck and God Speed."

Esto fue muy divertido. He agregado esto a mi propio ~ / .bashrc.


por Nota (1), he probado en Tilda, funciona bien. Guake es similar a Tilda, pero está escrito en python, por lo que aún no sé sobre Guake.
stazher

0

si estás usando bash, creo que este comando te ayudará:

which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))


0

Si estaba usando ZSH, hay una solución mejor (más rápida), que solo usa los componentes integrados de ZSH y los manipula /proc/$pid/{stat,cmdline}directamente.

get-terminal-emulator() {
    if [[ $TTY = "/dev/tty"* ]]; then
        echo "linux-console"
        return
    fi
    local pid=$$ name=''
    while true; do
        proc_stat=(${(@f)$(</proc/${pid}/stat)})
        name=${proc_stat[2]//[()]/}
        case "${name}" in
            gnome-terminal|konsole|rxvt|xterm)
                echo "${name}"; return ;;
            python*)
                local cmdline=(${(@f)$(</proc/${pid}/cmdline)})
                if [[ "$cmdline" =~ "\\bguake.main\\b" ]]; then
                    echo "guake"; return
                fi
                ;;
        esac
        if test "$pid" = "1" -o "$pid" = ""; then
            echo "unknown"
            return
        fi
        pid=${proc_stat[4]}       
    done
}
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.