Séquences d'échappement en sortie du script appelé depuis l'application ncurses

14

J'exécute actuellement mcabber en tant que client Jabber (qui utilise ncurses) dans une session tmux sur mon serveur domestique. Localement, j'exécute iTerm2 en tant qu'émulateur de terminal, qui prend en charge le déclenchement de notifications de grognement via des séquences d'échappement de caractères.

Remarque: Tout echodans cette question fonctionne comme printf %b, ou echo -een bash et GNU echo.

Par exemple, echo "\e]9;foobar\007"iTerm2 envoie un message Growl avec le texte "foobar".

Cependant, lors d'une session tmux, les séquences d'échappement sont absorbées. Par conséquent, l'utilisation de la séquence d'échappement de caractères propriétaire \Ptmuxpeut être utilisée comme ceci:

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

Cela déclenche un message de grognement depuis une session tmux.

Cependant, lorsque j'utilise ceci dans mon script d'événement mcabber qui se déclenche lorsqu'un nouveau message est reçu, aucune notification n'est déclenchée, comme si l'écho était envoyé au mauvais terminal.

Je suppose que cela a à voir avec le mcabber qui déclenche le script est une application ncurses donc la sortie de mon script bash normal se perd et iTerm 2 ne le voit jamais.

J'ai également essayé d'appeler smcup sans succès avant de me faire l'écho de certaines idées que j'ai découvertes

tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG\007\e\\"
tput rmcup

Je suppose que cela ne fonctionne pas car le problème n'est pas de revenir à la "vraie fenêtre de terminal", mais de diriger davantage la sortie vers la fenêtre ncurses.

Des idées sur celui-ci?

BinaryBucks
la source

Réponses:

1

La raison pour laquelle un script d'événement ne parvient pas à envoyer un message "Growler" est qu'il mcabberferme les flux d' entrée, de sortie et d'erreur standard lorsqu'il exécute une commande d'événement. Vous pouvez le voir dans 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);

Cela permet au script d'événement de s'exécuter sans interférer avec les flux utilisés par mcabber.

Il n'y a pas de mode ncurses spécial interceptant le message (après tout, il tmuxest déjà en cours d'exécution en tant qu'application terminfo). Vous pouvez probablement contourner le problème en redirigeant votre echo(de préférence printf) vers /dev/tty, par exemple,

#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty
Thomas Dickey
la source
0

Les programmes tmux et screen ne passent pas directement par les séquences d'échappement. Ils présentent un type de terminal à l'application (type de terminal d'écran), et est lui-même une application ncurses vers un autre terminal. En fait, c'est quelque chose comme un traducteur de terminal. Alors oui, il consomme (ou supprime) des séquences pour un type de terminal "écran", et met en place un tampon que vous voyez. Ensuite, il prend ces événements de changement de tampon et utilise le type de terminal que vous utilisez actuellement pour afficher le tampon actuel. Ainsi, l'application d'origine et le terminal de visualisation sont découplés.

Keith
la source
0

Si vous deviez mettre quelque chose comme ...

export "PTTY=$(tty)"

... dans votre /etc/profilealors pour chaque nouveau -lshell ogin que vous invoqueriez (ce qui se produit généralement lorsque vous ouvrez une nouvelle fenêtre de terminal), cette variable d'environnement serait mise à la disposition de tous ses processus enfants - qui devraient inclure tmuxet tous ses enfants .

Cela devrait vous permettre de faire ...

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

... et ainsi passer directement à travers toutes les ptycouches qui pourraient exister entre votre shell actuel et l'émulateur de terminal que vous utilisez.

mikeserv
la source
0

Si le problème est que la sortie de votre script bash se perd, vous pouvez gagner la bataille avec la redirection:

echo "\ ePtmux; \ e \ e] 9; foobar \ 007 \ e \"> / dev / tty

Cependant, je soupçonne que le vrai problème est que vous devriez utiliser echo -eafin que bash traite les séquences d'échappement dans votre chaîne.

aecolley
la source