Secuencias de escape en la salida del script llamado desde la aplicación ncurses

Secuencias de escape en la salida del script llamado desde la aplicación ncurses

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 echoen esta pregunta funciona como printf %bo echo -een 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 \Ptmuxse 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 quemcabbercierra 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/profileentonces para cada nuevo -lshell 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 tmuxa todos sus procesos secundarios.

Esto debería permitirle hacer...

printf '\033]9;foobar\007' >"$PTTY"

...y así saltar directamente a través de cualquier ptycapa 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 -epara que bash procese las secuencias de escape en tu cadena.

información relacionada