Ich verwende derzeit mcabber als meinen Jabber-Client (der ncurses verwendet) in einer tmux-Sitzung auf meinem Homeserver. Lokal verwende ich iTerm2 als Terminalemulator, der das Auslösen von Growl-Benachrichtigungen durch Zeichen-Escape-Sequenzen unterstützt.
Hinweis: Alles echo
in dieser Frage funktioniert wie printf %b
oder echo -e
in Bash und GNU echo
.
veranlasst iTerm2 beispielsweise echo "\e]9;foobar\007"
, eine Growl-Nachricht mit dem Text „foobar“ zu senden.
Während einer tmux-Sitzung werden die Escape-Sequenzen jedoch aufgebraucht. Daher \Ptmux
kann die Verwendung der proprietären Zeichen-Escape-Sequenz wie folgt erfolgen:
echo "\ePtmux;\e\e]9;foobar\007\e\\"
Dies löst innerhalb einer Tmux-Sitzung eine Growl-Meldung aus.
Wenn ich dies jedoch in meinem Mcabber-Ereignisskript verwende, das ausgelöst wird, wenn eine neue Nachricht empfangen wird, wird keine Benachrichtigung ausgelöst, als ob das Echo an das falsche Terminal gesendet würde.
Ich nehme an, das hat damit zu tun, dass es sich bei dem Mcabber, der das Skript auslöst, um eine Ncurses-Anwendung handelt, sodass die Ausgabe meines normalen Bash-Skripts verloren geht und iTerm 2 sie nie sieht.
Ich habe auch versucht, smcup ohne Erfolg aufzurufen, bevor ich gemäß einiger Ideen, die ich entdeckt habe, ein Echo ausgab
tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG\007\e\\"
tput rmcup
Ich nehme an, dass dies nicht funktioniert, da das Problem nicht darin besteht, zum „echten Terminalfenster“ zurückzuwechseln, sondern eher darin, die Ausgabe an das Ncurses-Fenster zu leiten.
Irgendwelche Ideen hierzu?
Antwort1
Der Grund, warum ein Event-Skript keine "Growler"-Nachricht senden kann, ist, dassmcabber
schließt die Standardeingabe,Ausgabeund Fehlerströme, wenn ein Ereignisbefehl ausgeführt wird. Sie können dies sehen inhooks.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 vonmcabber
.
Es gibt keinen speziellen Ncurses-Modus, der die Nachricht abfängt (schließlich tmux
istbereitsläuft als Terminfo-Anwendung). Sie können das Problem wahrscheinlich umgehen, indem Sie echo
(vorzugsweise printf
) auf umleiten /dev/tty
, z. B.
#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty
Antwort2
Die tmux- und screen-Programme leiten Escape-Sequenzen nicht direkt weiter. Sie präsentieren der Anwendung eine Art Terminal (Bildschirmterminaltyp) und sind selbst eine Ncurses-App für ein anderes Terminal. Tatsächlich ist es so etwas wie ein Terminalübersetzer. Es verbraucht also Sequenzen für einen „Bildschirm“-Terminaltyp (oder verwirft sie) und erstellt einen Puffer, den Sie sehen. Dann nimmt es diese Pufferänderungsereignisse und verwendet die Art von Terminal, die Sie gerade verwenden, um den aktuellen Puffer anzuzeigen. Die ursprüngliche App und das Anzeigeterminal sind also entkoppelt.
Antwort3
Wenn Sie etwas wie ... eingeben würden.
export "PTTY=$(tty)"
...in Ihrem /etc/profile
then für jede neue -l
Ogin-Shell, die Sie aufrufen würden(was im Allgemeinen passiert, wenn Sie ein neues Terminalfenster öffnen)Diese Umgebungsvariable würde allen ihren untergeordneten Prozessen zur Verfügung gestellt – und dazu gehören tmux
auch alle ihre untergeordneten Prozesse.
Dies sollte Ihnen Folgendes ermöglichen:
printf '\033]9;foobar\007' >"$PTTY"
... und überspringen Sie dabei alle pty
Ebenen, die möglicherweise zwischen Ihrer aktuellen Shell und dem von Ihnen verwendeten Terminalemulator vorhanden sind.
Antwort4
Wenn das Problem darin besteht, dass die Ausgabe Ihres Bash-Skripts verloren geht, können Sie den Kampf mit einer Umleitung gewinnen:
echo "\ePtmux;\e\e]9;foobar\007\e\" > /dev/tty
Ich vermute jedoch, dass das eigentliche Problem darin liegt, dass Sie es verwenden sollten, echo -e
damit Bash die Escape-Sequenzen in Ihrer Zeichenfolge verarbeitet.