Respuestas:
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
bash: [: too many arguments
. Tengo bash v4.2.24, python v2.7.3 si ayuda.
Prueba esto:
echo $TERM
Esto es más autoritario, pero sus programas podrían estropearlo. Sin embargo, en el mío, dice xterm
y en ttys dice linux
, lo que creo que significa Consola Linux.
$TERM
es 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 $TERM
regresa xterm
aunque 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
.
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/^.* //')
En muchos sistemas Linux echo $TERM
regresarxterm
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: ps
es "estado del proceso"
La opción ps -o
es 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 -p
es "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 .
-o
lista 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!
-p
de 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.
Usar pstree
y awk
es la forma más fácil:
pstree -sA $$ | awk -F "---" '{ print $2 }'
pstree
of $$
(el proceso actual).Los pstree
argumentos:
-s
: mostrar los padres de un proceso-A
: muestra la salida en ASCII puro.La awk
herramienta escanea un patrón y un -F
argumento se utiliza para dividir los procesos.
'{ print $2 }'
le dice a awk
generar solo el segundo patrón de coincidencia (en este caso, el nombre del emulador de terminal).$2
? En mi caso, lo que se canaliza es en awk
realidad systemd---lightdm---lightdm---upstart---gnome-terminal----bash---pstree
...
xfsettingsd
lugar del terminal que estoy usando.
pstree -sA $$ | head -n1 | awk -F "---" '{ print $(NF-1) }'
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 ps
o 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.
si estás usando bash, creo que este comando te ayudará:
which $(ps -o 'cmd=' -p $(ps -o 'ppid=' -p $$))
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
}
container
después de la definición.