Sequências de escape na saída do script chamada do aplicativo ncurses

14

Atualmente, estou executando o mcabber como meu cliente Jabber (que usa ncurses) em uma sessão tmux no meu servidor doméstico. Localmente, executo o iTerm2 como um emulador de terminal, que suporta o acionamento de notificações de rosnado por meio de seqüências de escape de caracteres.

Nota: Tudo echonesta questão funciona como printf %b, ou echo -eno bash e no GNU echo.

por exemplo, echo "\e]9;foobar\007"faz com que o iTerm2 envie uma mensagem Growl com o texto "foobar".

No entanto, quando em uma sessão tmux, as seqüências de escape são consumidas. Portanto, o uso da sequência de escape de caracteres proprietários \Ptmuxpode ser usado assim:

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

Isso aciona uma mensagem de rosnado de dentro de uma sessão do tmux.

No entanto, quando eu uso isso no meu script de evento mcabber que é acionado quando uma nova mensagem é recebida, nenhuma notificação é acionada, como se o eco fosse enviado para o terminal errado.

Suponho que isso tenha a ver com o mcabber que aciona o script é um aplicativo ncurses, para que a saída do meu script bash normal se perca e o iTerm 2 nunca o veja.

Eu também tentei chamar smcup sem sucesso antes de ecoar de acordo com algumas idéias que descobri

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

Suponho que isso não funcione, pois o problema não está voltando para a "janela real do terminal", mas direcionando mais a saída na janela ncurses.

Alguma ideia sobre este?

BinaryBucks
fonte

Respostas:

1

A razão pela qual um script de evento falha ao enviar uma mensagem "growler" é que mcabberfecha os fluxos de entrada, saída e erro padrão quando executa um comando de evento. Você pode ver isso em 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);

Isso faz com que o script de evento seja executado sem interferir nos fluxos usados ​​por mcabber.

Não há um modo ncurses especial que intercepta a mensagem (afinal, tmux está sendo executado como um aplicativo terminfo). Provavelmente, você pode solucionar o problema redirecionando echo(de preferência printf) para /dev/tty, por exemplo,

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

Os programas tmux e screen não passam diretamente pelas seqüências de escape. Eles apresentam um tipo de terminal para o aplicativo (tipo de terminal de tela) e é um aplicativo necessário para outro terminal. Com efeito, é algo como um tradutor de terminal. Portanto, sim, ele consome (ou descarta) seqüências para um tipo de terminal "tela" e coloca um buffer que você vê. Em seguida, ele recebe esses eventos de alteração do buffer e usa qualquer tipo de terminal que você está usando atualmente para exibir o buffer atual. Portanto, o aplicativo original e o terminal de visualização são dissociados.

Keith
fonte
0

Se você colocar algo como ...

export "PTTY=$(tty)"

... no seu /etc/profileentão para cada novo -lshell ogin que você chamaria (o que geralmente acontece quando você abre uma nova janela de terminal), essa variável de ambiente seria disponibilizada a todos os processos filhos - o que deveria incluir tmuxe todos os filhos .

Isso deve permitir que você faça ...

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

... e, assim, pule diretamente as ptycamadas que possam existir entre o shell atual e o emulador de terminal que você está usando.

mikeserv
fonte
0

Se o problema é que a saída do seu script bash está se perdendo, você pode vencer a batalha com o redirecionamento:

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

No entanto, suspeito que o verdadeiro problema é que você deve estar usando echo -epara que o bash processe as seqüências de escape na sua string.

aecolley
fonte