Actualmente estoy ejecutando mcabber como mi cliente Jabber (que usa ncurses) en una sesión tmux en mi servidor doméstico. Localmente ejecuto iTerm2 como un emulador de terminal, que admite la activación de notificaciones de gruñidos a través de secuencias de escape de caracteres.
Nota: Todo echo
en esta pregunta funciona como printf %b
o echo -e
en bash y GNU echo
.
por ejemplo, echo "\e]9;foobar\007"
hace que iTerm2 envíe un mensaje Growl con el texto "foobar".
Sin embargo, en una sesión tmux, las secuencias de escape se consumen. Por lo tanto, el uso de la secuencia de escape de caracteres patentada \Ptmux
se puede utilizar de esta manera:
echo "\ePtmux;\e\e]9;foobar\007\e\\"
Esto activa un mensaje de gruñido desde dentro de una sesión tmux.
Sin embargo, cuando uso esto en mi secuencia de comandos de eventos mcabber que se activa cuando se recibe un mensaje nuevo, no se activa ninguna notificación, como si el eco se enviara al terminal equivocado.
Supongo que esto tiene que ver con que mcabber que activa el script es una aplicación ncurses, por lo que el resultado de mi script bash normal se pierde y iTerm 2 nunca lo ve.
También intenté llamar a smcup sin éxito antes de hacerme eco de algunas ideas que descubrí.
tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG\007\e\\"
tput rmcup
Supongo que esto no funciona ya que el problema no es volver a la "ventana de terminal real", sino más bien dirigir la salida a la ventana de ncurses.
¿Alguna idea sobre éste?
Respuesta1
La razón por la que un script de evento no puede enviar un mensaje "gruñidor" es quemcabber
cierra la entrada estándar,produccióny flujos de error cuando ejecuta un comando de evento. Puedes ver esto enhooks.c
:
if ((pid=fork()) == -1) {
scr_LogPrint(LPRINT_LOGNORM, "Fork error, cannot launch external command.");
g_free(datafname);
return;
}
if (pid == 0) { // child
// Close standard file descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (execl(extcmd, extcmd, arg_type, arg_info, bjid, arg_data,
(char *)NULL) == -1) {
// scr_LogPrint(LPRINT_LOGNORM, "Cannot execute external command.");
exit(1);
}
}
g_free(datafname);
Eso hace que el script del evento se ejecute sin interferir con las transmisiones utilizadas pormcabber
.
No existe un modo especial de ncurses para interceptar el mensaje (después de todo, tmux
¿es así?yaejecutándose como una aplicación terminfo). Probablemente pueda solucionar el problema redirigiendo su echo
(preferiblemente printf
) a /dev/tty
, por ejemplo,
#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty
Respuesta2
Los programas tmux y screen no pasan directamente por secuencias de escape. Presentan un tipo de terminal a la aplicación (tipo de terminal de pantalla) y son en sí mismos una aplicación ncurses para otro terminal. En efecto, es algo así como un traductor de terminal. Entonces sí, consume (o descarta) secuencias para un tipo de terminal de "pantalla" y crea un búfer que ve. Luego toma esos eventos de cambio de búfer y usa cualquier tipo de terminal que esté usando actualmente para mostrar el búfer actual. Entonces la aplicación original y el terminal de visualización están desacoplados.
Respuesta3
Si pusieras algo como...
export "PTTY=$(tty)"
...en tu /etc/profile
entonces para cada nuevo -l
shell de ogin que invocarías(que es lo que generalmente sucede cuando abres una nueva ventana de terminal)esa variable de entorno estaría disponible para todos sus procesos secundarios, que deberían incluir tmux
a todos sus procesos secundarios.
Esto debería permitirle hacer...
printf '\033]9;foobar\007' >"$PTTY"
...y así saltar directamente a través de cualquier pty
capa que pueda existir entre su shell actual y el emulador de terminal que está utilizando.
Respuesta4
Si el problema es que la salida de tu script bash se pierde, entonces puedes ganar la batalla con la redirección:
echo "\ePtmux;\e\e]9;foobar\007\e\" > /dev/tty
Sin embargo, sospecho que el verdadero problema es que deberías usarlo echo -e
para que bash procese las secuencias de escape en tu cadena.