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

14

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ñido a través de secuencias de escape de caracteres.

Nota: Todo echoen esta pregunta funciona como printf %b, o echo -een bash y GNU echo.

Por ejemplo, echo "\e]9;foobar\007"iTerm2 envía un mensaje de Growl con el texto "foobar".

Sin embargo, cuando está en una sesión tmux, las secuencias de escape se comen. Por lo tanto, el uso de la secuencia de escape de caracteres patentada \Ptmuxpuede usarse así:

echo "\ePtmux;\e\e]9;foobar\007\e\\"

Esto desencadena un mensaje gruñido desde una sesión tmux.

Sin embargo, cuando uso esto en mi script de evento mcabber que se dispara cuando se recibe un nuevo mensaje, no se activa ninguna notificación, como si el eco se enviara a la terminal incorrecta.

Supongo que esto tiene que ver con ese 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 hacer 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 cambiar a la "ventana de terminal real", sino dirigir más la salida en la ventana ncurses.

¿Alguna idea sobre éste?

BinaryBucks
fuente

Respuestas:

1

La razón por la cual un script de evento no puede enviar un mensaje "growler" es que mcabbercierra los flujos de entrada, salida y error estándar cuando ejecuta un comando de evento. Puedes ver esto en hooks.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 de evento se ejecute sin interferir con las secuencias utilizadas por mcabber.

No hay un modo especial ncurses que intercepte el mensaje (después de todo, yatmux se está ejecutando 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
Thomas Dickey
fuente
0

Los programas tmux y screen no pasan directamente a través de secuencias de escape. Presentan un tipo de terminal para la aplicación (tipo de terminal de pantalla), y es en sí una aplicación ncurses para otro terminal. En efecto, es algo así como un traductor terminal. Entonces sí, consume (o descarta) secuencias para un tipo de terminal de "pantalla" y coloca un búfer que puede ver. 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. Por lo tanto, la aplicación original y el terminal de visualización están desacoplados.

Keith
fuente
0

Si tuvieras que poner algo como ...

export "PTTY=$(tty)"

... en su caso /etc/profile, por cada nuevo -lshell ogin invocaría (que es lo que generalmente sucede cuando abre una nueva ventana de terminal) esa variable de entorno estaría disponible para todos sus procesos secundarios, que deberían incluir tmuxy todos sus elementos secundarios .

Esto debería permitirle hacer ...

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

... y, por lo tanto, salta a través de cualquier ptycapa que pueda existir entre tu shell actual y el emulador de terminal que estás utilizando.

mikeserv
fuente
0

Si el problema es que el resultado de su script bash se está perdiendo, entonces puede 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ía usarlo echo -epara que bash procese las secuencias de escape en su cadena.

Aecolley
fuente