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 echo
nesta questão funciona como printf %b
ou echo -e
em 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 \Ptmux
pode 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" é quemcabber
fecha 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
éjá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/profile
then para cada novo -l
shell 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 tmux
todos os seus filhos.
Isso deve permitir que você faça ...
printf '\033]9;foobar\007' >"$PTTY"
...e, assim, pule quaisquer pty
camadas 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 -e
para que o bash processe as sequências de escape em sua string.