Escape seqüências na saída do script chamado do aplicativo ncurses

14

Atualmente, estou executando o mcabber como meu cliente Jabber (que usa ncurses) em uma sessão tmux no meu homeserver. Localmente eu corro o iTerm2 como um emulador de terminal, que suporta o acionamento de notificações de growl através de seqüências de escape de caracteres.

Nota: Todos os echo nesta questão funcionam como printf %b , ou echo -e no bash e GNU echo .

por exemplo. echo "\e]9;foobar\Ptmux7" faz o iTerm2 enviar uma mensagem Growl com o texto "foobar".

No entanto, quando em uma sessão do tmux, as seqüências de escape são consumidas. Portanto, usando a seqüência de escape de caractere proprietário %code% pode ser usado assim:

echo "\ePtmux;\e\e]9;foobar
tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG
echo "\ePtmux;\e\e]9;foobar
tput smcup
echo "\ePtmux;\e\e]9;$FROM: $MSG%pre%7\e\"
tput rmcup
7\e\"
7\e\" tput rmcup
7\e\"

Isso dispara uma mensagem de grunhido 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 aquele mcabber que aciona o script é um aplicativo ncurses para que a saída do meu script bash normal seja perdida e o iTerm 2 nunca o veja.

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

%pre%

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

Alguma idéia sobre essa?

    
por BinaryBucks 22.03.2012 / 11:47

4 respostas

1

A razão pela qual um script de evento não envia uma mensagem "growler" é que mcabber fecha a entrada padrão, saída e fluxos de erro quando executa uma 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á nenhum modo ncurses especial interceptando a mensagem (afinal, tmux está sendo executado como um aplicativo terminfo). Provavelmente, você pode contornar o problema redirecionando seu echo (de preferência printf ) para /dev/tty , por exemplo,

#!/bin/sh
printf '3Ptmux;33]9;foobar
  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);
73\' >/dev/tty
    
por 27.06.2016 / 02:48
0

Os programas tmux e screen não passam diretamente pelas seqüências de escape. Eles apresentam um tipo de terminal para a aplicação (tipo de terminal de tela), e é em si um aplicativo ncurses para outro terminal. Na verdade, é algo como um tradutor de terminal. Então, sim, consome (ou descarta) seqüências para um tipo de terminal de "tela", e coloca um buffer que você vê. Em seguida, ele leva esses eventos de alteração de buffer e usa qualquer tipo de terminal que você está usando atualmente para exibir o buffer atual. Assim, o aplicativo original e o terminal de visualização são dissociados.

    
por 25.03.2012 / 07:10
0

Se você fosse colocar algo como ...

export "PTTY=$(tty)"

... no seu /etc/profile para cada nova shell -l ogin que você invocaria (o que geralmente acontece quando você abre uma nova janela de terminal) essa variável de ambiente seria feita disponível para todos os seus processos filhos - que devem incluir tmux e todos os seus filhos.

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

printf '3]9;foobar
export "PTTY=$(tty)"
7' >"$PTTY"

... e, portanto, pula direto através de qualquer pty camadas que possam existir entre o seu shell atual e o emulador de terminal que você está usando.

    
por 20.12.2014 / 22:54
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%bl0ck_qu0te%7\e\" > /dev/tty

No entanto, suspeito que o problema real é que você deve usar echo -e para que o bash processe as seqüências de escape na sua string.

    
por 23.01.2015 / 22:14