Estou adaptando a resposta de Marcus Müller a uma pergunta que fiz na semana passada - um script que redireciona seu stdout para uma sessão tmux para renderizar sequências de escape ANSI e, em seguida, captura a renderização do painel como a saída real do script. Eu sei que não é nada útil, já que você pode imprimi-lo diretamente no stdout e ter o mesmo resultado, mas é apenas uma demonstração para brincar, para trazer o código para um projeto maior e mais complexo de explicar, onde preciso desse recurso :
#!/bin/zsh
tmpdir="$(mktemp -d)"
fifo="${tmpdir}/fifo"
mkfifo "$fifo"
tmux new-session -d -s aux "while true; do cat ${fifo}; done"
exec 3>&1 1>"$fifo"
echo foo
echo bar
tput home
echo -n b
exec 1>&3 3>&-
tmux capture-pane -t "aux" -p -S0 -E1
tmux kill-session -t aux
rm -rf $tmpdir
quais saídas (e devem):
boo
bar
Estou interessado em simplificar o código. É possível usar algum truque que funcione com o redirecionamento stdin em vez de um fifo que precisa ser mantido? Posso usar uma linha de alguma forma que continue imprimindo tudo e feche a sessão automaticamente quando terminar?
Eu tentei e brinquei com tmux pipe-pane, buffer, send-keys e run-shell e não consegui. Principalmente quando a sessão leva stdin como se você tivesse escrito um comando no console, não como o stdin do script que um comando/script que está rodando
Eu sinto que deve ser simplificável de alguma forma.
Pergunte
tmux
o quetty
está atribuído ao único painel da única janela da nova sessão. Em seguida, imprima nele.Obter informações
tmux display-message -p
é bastante útil em geral. No seu caso, você pode obter informações sobre o tty diretamente emtmux new-session
; e você não precisa datty
variável. Você pode configurar o redirecionamento sem etapas preliminares, como esta:Note
tail -f /dev/null
é apenas um comando para manter o painel tmux "vivo". O script não tenta enviar nada para este comando; em vez disso, imprime no tty correto. Esta resposta não resolve o título ("Redirecionando stdout de um script como o stdin de outro script/comando em execução em uma sessão tmux"), mas fornece a funcionalidade desejada.Não estou claro exatamente o que você está perguntando. Você está aceitando o conceito de usar o tmux para processar as sequências de escape, mas deseja apenas eliminar o FIFO?
Tente apenas produzir a saída desejada em tmux :
e deixe de lado o material FIFO.
PS Você deve citar variáveis do shell, como
$fifo
e$tmpdir
. Você realmente não precisa citar strings constantes compostas de caracteres que não sejam espaços em branco, como"aux"
.Eu não acho que você possa fazer algo assim, pois
tmux
fechará todos os fds acima de 2 recebidos (e 0, 1, 2 também quando desconectados).Veja
close_range(3, 4294967295, 0)
ou equivalente nastrace
saída (ou equivalente) ou nasclosefrom(STDERR_FILENO + 1)
chamadas na fonte.Portanto, você precisará passar os dados de alguma outra maneira, por meio de um canal nomeado como você faz ou de uma variável de ambiente (mas não pode conter caracteres NUL) ou incorporado no código shell executado por
tmux
um soquete, arquivo temporário, memória compartilhada , nenhum dos quais será realmente mais simples ou confiável.Existem vários problemas em sua abordagem:
tmux
escolher o nome da sessão e recuperá-lo através da-P
opçãonew-session
.capture-pane
, não há garantia de quecat
terá terminado ou mesmo iniciado. Você está fazendo esse loop + kill em vez de dizer à sessão do tmux para sair quando você recuperar o conteúdo do painel.$fifo
dentro do código shell executado na nova sessão. Melhor passar como uma variável de ambiente.mktemp
oumkfifo
.~/.tmux.conf
o que pode interferir no processamentoTERM=tmux
para o ambiente detput
(ou equivalente interno do zshechoti
), pois é umtmux
emulador de terminal que acabará interpretando em vez do terminal host no qual você executa o script, então você precisa enviar as sequências de escape que ele prefere do que o terminal host entenderá¹.-S0 -E1
, você está capturando apenas as duas primeiras linhas visíveis do painelEntão, talvez algo como:
Então, por exemplo:
(observe todos os bytes 0x0a (LF), pois minha janela de terminal tem 60 linhas de altura).
( isenção de responsabilidade : eu não sou um usuário do tmux, então pode muito bem haver maneiras mais inteligentes ou corretas de fazer isso lá)
¹ Embora, no caso do
home
recurso, seja improvável que faça diferença na prática, pois é improvável que você esteja usando um terminal para o qual ahome
sequência de escape seja diferente daquela datmux
'própria emulação (\e[H
).