Dado um comando que altera seu comportamento quando sua saída está indo para um terminal (por exemplo, produzir saída colorida), como essa saída pode ser redirecionada em um pipeline enquanto preserva o comportamento alterado? Deve haver uma utilidade para isso, da qual não estou ciente.
Alguns comandos, como grep --color=always
, possuem sinalizadores de opção para forçar o comportamento, mas a questão é como solucionar os programas que dependem apenas do teste de seu descritor de arquivo de saída.
Se isso importa, meu shell está bash
no Linux.
Respostas:
Você pode obter o que precisa usando
unbuffer
.unbuffer
é umtcl
/expect
script. Olhe a fonte, se quiser. Observe também a seção CAVEATS no man.Observe também que ele não executa aliases como:
a menos que se adicione um truque, como observado por Stéphane Chazelas:
Se você fizer um
alias unbuffer='unbuffer '
(observe o espaço à direita), os aliases serão expandidos depoisunbuffer
.fonte
alias unbuffer='unbuffer '
(observe o espaço à direita), os aliases serão expandidos depoisunbuffer
.unbuffer
isto é!sudo apt install expect
- Isso não estava claro.Uma história de conjuntos de ferramentas
Você não é a primeira pessoa a querer essa ferramenta. As pessoas estão querendo essas ferramentas há 30 anos. E eles existem há quase tanto tempo também.
A primeira ferramenta para esse tipo de coisa foi o pacote "pty" de Daniel J. Bernstein, descrito por Rich Salz como uma "faca Ginsu", que Bernstein escreveu na virada da década de 1990 para enganar o nethack (sic!). A versão 4 do pacote "pty" foi publicada em 1992 para
comp.sources.unix
(volume 25 edições 127 a 135). Ainda é localizável na Internet. Paul Vixie descreveu na época:Mais tarde, Bernstein atualizou isso, em algum momento antes de 1999-04-07, com um pacote "ptyget", que ele anunciou:
Esse pacote separado era o pacote "sess".
"ptyget" é, aliás, notável por exemplificar uma versão muito antiga e uma das poucas instâncias publicadas do sistema de compilação "redo" nunca publicado de Berstein.
dependon
é um precursor claro deredo-ifchange
.Uso
ptybandage
ptybandage
é o que as pessoas geralmente querem em uma sessão de login. Seu principal caso de uso é criar programas sensíveis a que suas entradas, saídas ou erros padrão estejam conectados aos terminais, operem dessa maneira, mesmo que estejam de fato em pipelines de shell ou tenham seus descritores de arquivo padrão redirecionados para o arquivo.É preciso um comando a ser executado (que tem de ser um comando externo apropriado, é claro) e executa-lo de tal maneira que ele acha que seu padrão de entrada, saída e erro estão ligados a um terminal, conectando aqueles através de
ptybandage
's entrada, saída e erro padrão original.Ele lida com as nuances da execução sob as caixas de controle de tarefas, assegurando que o caractere STOP do terminal não apenas pare,
ptybandage
mas também interrompa a execução do programa conectado ao terminal interno.ptyrun
ptyrun
é o que as pessoas geralmente querem nos servidores de rede TCP. Seu caso de uso principal são ambientes de execução remota que não configuraram terminais, executando programas que não operam como desejado quando não há terminal.Ele não espera estar sendo executado sob um shell de controle de tarefas e, se o comando que está sendo executado recebe um sinal de parada, é simplesmente reiniciado.
Conjuntos de ferramentas disponíveis
Dru Nelson publica as versões "pty" 4 e "ptyget".
Paul Jarc publica uma versão fixa do ptyget, que tenta lidar com o dispositivo pseudo-terminal específico do sistema operacional ioctls no original que os sistemas operacionais na verdade não fornecem mais.
O pacote fonte nosh vem com scripts
ptybandange
e práticasptyrun
, que usam aexecline
ferramenta de Laurent Bercot e os comandos de gerenciamento pseudo-terminal do próprio pacote nosh. A partir da versão 1.23 do nosh, eles estão disponíveis pré-empacotados no pacote nosh-terminal-extras. (As versões anteriores os forneciam apenas para pessoas que criavam a partir da fonte.)Alguns exemplos usam
Jurjgen Oskam usando
ptybandage
no AIX para alimentar a entrada de um documento aqui para um programa que é explicitamente aberto e lê seu terminal de controle para um prompt de senha:Andy Bradford usando
ptyrun
no OpenBSD sob daemontools e ucspi-tcp para tornar obgplgsh
programa de controle de roteador interativo acessível via rede, enquanto pensa que está falando com um terminal:Leitura adicional
redo
. Respostas dadas com freqüência.bgplgsh
. 8. Páginas de manual do OpenBSD.fonte
expect
?Você pode usar o socat para iniciar seu processo com um pty conectado e fazer com que o socat conecte a outra extremidade do pty a um arquivo. Qual AFAIU é exatamente o que você pediu:
Esse método fará com que o
isatty
chamadomy-command
retornetrue
e um processo que depende apenas dele será enganado para gerar códigos de controle. Observe que alguns processos (principalmentegrep
) também verificam o valor daTERM
variável de ambiente; portanto, você pode precisar configurá-lo para algo razoável, como"xterm"
fonte
Também há uma boa solução postada aqui no Superusuário por KarlC :
Compile uma pequena biblioteca compartilhada:
Em seguida, diga ao seu comando para carregar essa
isatty(3)
substituição dinamicamente:Isso pode não funcionar para todos os comandos existentes, pode até quebrar alguns de maneiras inesperadas, mas provavelmente funcionaria na maioria dos casos.
fonte
DYLD_INSERT_LIBRARIES=./isatty.so DYLD_FORCE_FLAT_NAMESPACE=y mycommand
Que tal usar
script(1)
?Por exemplo:
Salvará a
ls
saídaout_file
com os códigos de cores preservados.fonte
out_file
com suas cores?less -R
. Nesse caso, porém, eu queria que a saída continuasse no pipeline, que acabou no meu terminal. Usandocat
para ilustração, era algo comoscript -q -c 'ls -G' /dev/null | cat
, que suprimetypescript
completamente o arquivo, deixando apenas a saída do programa.-
) comoscript
arquivo de saída, por exemple:script -q -c 'ls -G' -
Baseado na resposta de @ Amir , aqui está um script que gera e inclui a biblioteca em tempo de execução:
fonte