Escape-Sequenzen in der Ausgabe eines Skripts, das von der Anwendung ncurses aufgerufen wird

14

Ich führe derzeit mcabber als Jabber-Client (der ncurses verwendet) in einer tmux-Sitzung auf meinem Homeserver aus. Vor Ort starte ich iTerm2 als Terminal-Emulator, der das Auslösen von Growl-Benachrichtigungen durch Zeichen-Escape-Sequenzen unterstützt.

Hinweis: Alles echoin dieser Frage funktioniert wie printf %b, oder echo -ein Bash und GNU echo.

zB echo "\e]9;foobar\007"macht iTerm2 eine Growl Nachricht mit dem Text „foobar“ senden.

In einer tmux-Sitzung werden die Escape-Sequenzen jedoch aufgefressen. Daher kann die proprietäre Zeichen-Escape-Sequenz \Ptmuxfolgendermaßen verwendet werden:

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

Dies löst eine Growl-Nachricht innerhalb einer tmux-Sitzung aus.

Wenn ich dies jedoch in meinem mcabber-Ereignisskript verwende, das beim Empfang einer neuen Nachricht ausgelöst wird, wird keine Benachrichtigung ausgelöst, als ob das Echo an das falsche Terminal gesendet würde.

Ich nehme an, das hat mit dem mcabber zu tun, der das Skript auslöst. Es handelt sich um eine Ncurses-Anwendung, sodass die Ausgabe meines normalen Bash-Skripts verloren geht und iTerm 2 sie nie sieht.

Ich habe auch versucht, smcup ohne Erfolg anzurufen, bevor ich mich einigen Ideen angeschlossen habe, die ich entdeckt habe

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

Ich nehme an, dass dies nicht funktioniert, da das Problem nicht auf das "echte Terminalfenster" zurückschaltet, sondern die Ausgabe eher auf das ncurses-Fenster lenkt.

Irgendwelche Ideen dazu?

BinaryBucks
quelle

Antworten:

1

Der Grund, warum ein Ereignisskript keine "Growler" -Nachricht sendet, besteht darin, dass mcabberdie Standardeingabe-, Ausgabe- und Fehlerströme geschlossen werden, wenn ein Ereignisbefehl ausgeführt wird. Sie können dies in sehen 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);

Dadurch wird das Ereignisskript ausgeführt, ohne die von verwendeten Streams zu beeinträchtigen mcabber.

Es gibt keinen speziellen ncurses - Modus die Nachricht abfängt (immerhin tmuxist bereits als Anwendung ausgeführt term). Sie können das Problem wahrscheinlich umgehen, indem Sie Ihre echo(vorzugsweise printf) an /dev/ttyz.

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

Die tmux- und screen-Programme durchlaufen die Escape-Sequenzen nicht direkt. Sie präsentieren der Anwendung eine Art von Terminal (Bildschirm-Terminal-Typ) und sind selbst eine verfluchte App für ein anderes Terminal. In der Tat ist es so etwas wie ein Terminal-Übersetzer. Ja, es verbraucht (oder verwirft) Sequenzen für einen "Bildschirm" -Terminaltyp und erstellt einen Puffer, den Sie sehen. Dann nimmt es diese Pufferänderungsereignisse und verwendet die Art von Terminal, die Sie aktuell verwenden, um den aktuellen Puffer anzuzeigen. So sind die ursprüngliche App und das Anzeigeterminal entkoppelt.

Keith
quelle
0

Wenn Sie etwas setzen würden wie ...

export "PTTY=$(tty)"

... in Ihrem /etc/profilethen würden Sie für jede neue -login-Shell (was normalerweise passiert, wenn Sie ein neues Terminalfenster öffnen) diese Umgebungsvariable für alle untergeordneten Prozesse verfügbar machen - einschließlich tmuxund aller untergeordneten Prozesse .

Dies sollte es Ihnen ermöglichen, ...

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

... und gehen Sie dabei alle ptyEbenen durch, die möglicherweise zwischen Ihrer aktuellen Shell und dem von Ihnen verwendeten Terminalemulator vorhanden sind.

mikeserv
quelle
0

Wenn das Problem darin besteht, dass die Ausgabe Ihres Bash-Skripts verloren geht, können Sie den Kampf mit der Umleitung gewinnen:

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

Ich vermute jedoch, dass das eigentliche Problem darin besteht, dass Sie verwenden sollten, echo -edamit bash die Escape-Sequenzen in Ihrer Zeichenfolge verarbeitet.

aecolley
quelle