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

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

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 sequências de escape de caracteres.

Nota: Tudo echonesta questão funciona como printf %bou echo -eem bash e 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 do tmux, as sequê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 tmux.

No entanto, quando eu uso isso em 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 fato de o mcabber que aciona o script ser um aplicativo ncurses, então a saída do meu script bash normal se perde e o iTerm 2 nunca o vê.

Também tentei ligar para smcup sem sucesso antes de ecoar de acordo com algumas ideias 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 é voltar para a "janela real do terminal", mas sim direcionar a saída para a janela ncurses.

Alguma ideia sobre este?

Responder1

A razão pela qual um script de evento falha ao enviar uma mensagem "growler" é quemcabberfecha a entrada padrão,saídae fluxos de erros quando executa um comando de evento. Você pode ver isso emhooks.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 do evento seja executado sem interferir nos fluxos usados ​​pelomcabber.

Não existe um modo especial de ncurses interceptando a mensagem (afinal, tmuxéexecutando como um aplicativo terminfo). Você provavelmente pode contornar o problema redirecionando seu echo(de preferência printf) para /dev/tty, por exemplo,

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

Responder2

Os programas tmux e screen não passam diretamente pelas sequências de escape. Eles apresentam um tipo de terminal para o aplicativo (tipo de terminal de tela) e são em si um aplicativo ncurses para outro terminal. Na verdade, é algo como um tradutor de terminal. Então sim, ele consome (ou descarta) sequências para um tipo de terminal "tela" e coloca um buffer que você vê. Em seguida, ele pega esses eventos de mudança de 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.

Responder3

Se você colocasse algo como...

export "PTTY=$(tty)"

... no seu /etc/profilethen para cada novo -lshell ogin que você invocaria(que é o que geralmente acontece quando você abre uma nova janela de terminal)essa variável de ambiente seria disponibilizada para todos os seus processos filhos - que deveriam incluir tmuxtodos os seus filhos.

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

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

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

Responder4

Se o problema é que a saída do seu script bash está sendo perdida, 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ê deveria usar echo -epara que o bash processe as sequências de escape em sua string.

informação relacionada