Sekwencje specjalne w danych wyjściowych skryptu wywoływanego z aplikacji ncurses

14

Obecnie uruchamiam mcabber jako mojego klienta Jabber (który używa ncurses) w sesji tmux na moim serwerze domowym. Lokalnie uruchamiam iTerm2 jako emulator terminala, który obsługuje wyzwalanie powiadomień warczących poprzez sekwencje specjalne znaków.

Uwaga: Wszystko echow tym pytaniu działa jak printf %b, lub echo -ew bash i GNU echo.

np. echo "\e]9;foobar\007"zmusza iTerm2 do wysłania wiadomości Growl z tekstem „foobar”.

Jednak podczas sesji tmux sekwencje ucieczki zostają pochłonięte. Dlatego przy użyciu zastrzeżonej sekwencji ucieczki znaków \Ptmuxmożna użyć w następujący sposób:

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

To uruchamia komunikat warczenia z sesji tmux.

Jednak gdy używam tego w skrypcie zdarzeń mcabber, który jest uruchamiany po otrzymaniu nowej wiadomości, żadne powiadomienie nie jest wyzwalane, tak jakby echo zostało wysłane do niewłaściwego terminala.

Przypuszczam, że ma to związek z tym mcabber, który uruchamia skrypt, jest aplikacją ncurses, więc dane wyjściowe z mojego normalnego skryptu bash giną, a iTerm 2 nigdy tego nie widzi.

Próbowałem też zadzwonić do smcup bez powodzenia, zanim powtórzyłem dostęp do niektórych odkrytych pomysłów

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

Przypuszczam, że to nie działa, ponieważ problemem nie jest powrót do „prawdziwego okna terminala”, ale bardziej ukierunkowanie wyjścia w oknie ncurses.

Jakieś pomysły na ten temat?

BinaryBucks
źródło

Odpowiedzi:

1

Powodem, dla którego skrypt zdarzenia nie wysyła komunikatu „warczenie”, jest to, że mcabberzamyka on standardowe strumienie wejściowe, wyjściowe i błędów podczas uruchamiania polecenia zdarzenia. Możesz to zobaczyć w 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);

To sprawia, że ​​skrypt zdarzeń działa bez zakłócania strumieni używanych przez mcabber.

Nie ma specjalnego trybu ncurses przechwytującego wiadomość (w końcu tmuxdziała już jako aplikacja terminfo). Prawdopodobnie możesz obejść ten problem, przekierowując echo(najlepiej printf) na /dev/ttynp.

#!/bin/sh
printf '\033Ptmux;\033\033]9;foobar\007\033\\' >/dev/tty
Thomas Dickey
źródło
0

Programy tmux i screen nie przechodzą bezpośrednio przez sekwencje specjalne. Prezentują one jeden rodzaj terminala dla aplikacji (typ terminala ekranowego) i sam jest aplikacją ncurses dla innego terminala. W efekcie jest to coś w rodzaju terminalnego tłumacza. Tak więc zużywa (lub odrzuca) sekwencje dla typu terminala „ekranowego” i umieszcza bufor, który widzisz. Następnie bierze te zdarzenia zmiany bufora i używa dowolnego rodzaju terminala, którego aktualnie używasz do wyświetlenia bieżącego bufora. Oryginalna aplikacja i terminal do przeglądania są oddzielone.

Keith
źródło
0

Jeśli miałbyś umieścić coś takiego ...

export "PTTY=$(tty)"

... w twoim /etc/profileprzypadku dla każdej nowej -lpowłoki Ogin, którą wywołałeś (co zwykle dzieje się, gdy otwierasz nowe okno terminala), ta zmienna środowiskowa byłaby dostępna dla wszystkich jej procesów potomnych - które powinny obejmować tmuxi wszystkie jej potomki .

To powinno umożliwić ci zrobienie ...

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

... i tym samym pomiń wszystkie ptywarstwy, które mogą istnieć między twoją bieżącą powłoką a używanym emulatorem terminala.

mikeserv
źródło
0

Jeśli problem polega na tym, że dane wyjściowe skryptu bash giną, możesz wygrać bitwę za pomocą przekierowania:

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

Podejrzewam jednak, że prawdziwym problemem jest to, że powinieneś używać echo -e, aby bash przetwarzał sekwencje specjalne w twoim ciągu.

Aecolley
źródło