tr
parece armazenar em buffer sua entrada, para que este comando LongRunningCommand|tr \\n ,
comece a produzir somente após a acumulação de alguns kilobytes de entrada do LongRunningCommand.
Existe uma maneira de forçar tr
a parar esse buffer ou qualquer outro comando que possa substituir novas linhas por outro caractere sem buffer?
PS: Eu já tentei as duas primeiras sugestões do Turn off buffering in pipe, sem sucesso.
stdbuf
no LongRunningCommand ou no tr, ou em ambos, de maneira diferente?stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
fping -q
diz "Não mostrar resultados por sonda, mas apenas o resumo final"; talvez seja necessário apenas uma longa escrita no final?tr
. Tente|stdbuf -i0 -o0 tr ...
Respostas:
Os comandos geralmente não armazenam em buffer suas entradas. Eles fariam um valor
read()
para um pedaço grande, mas, ao ler de um canal, se não houver muitos bytes no canal, aread()
chamada do sistema retornará com o máximo de caracteres existentes e o aplicativo geralmente trabalhará com isso, se puder .Uma exceção notável é a
mawk
que permaneceráread()
até que o buffer de entrada esteja cheio.Os aplicativos armazenam em buffer sua saída (stdout). O comportamento usual é que, se a saída estiver indo para um tty, o buffer será em linha (isto é, não começará a gravar no stdout até que tenha uma linha completa para a saída ou um bloco cheio por muito tempo). linha longa), enquanto que para todos os outros tipos de arquivo, o buffer é em blocos (ou seja, não começa a escrever até que haja um bloco completo para escrever (algo como 4KiB / 8KiB ... depende do software e do sistema )).
Portanto, no seu caso,
LongRunningCommand
provavelmente armazena em buffer sua saída em blocos (já que sua saída é um pipe e não um tty), etr
provavelmente armazena em buffer sua saída por linha, já que provavelmente é o terminal.Mas, como você remove todos os caracteres de nova linha de sua saída, ele nunca gera uma linha, portanto o buffer será por bloco.
Então, aqui você deseja desativar o buffer para ambos
LongRunningCommand
etr
. Nos sistemas GNU ou FreeBSD:Observe que se você deseja unir as linhas com uma vírgula, é melhor usar uma abordagem
paste -sd , -
. Dessa forma, a saída será finalizada por um caractere de nova linha (você provavelmente ainda precisará desativar o buffer).fonte
sed
. desculpe se foi chato - mas eu não percebi que era conhecimento geral. Eu acho que ele usa LD_PRELOAD.Para substituir novas linhas por
","
, você pode executarO GNU awk (
gawk
) e o Solarisnawk
serão executados com buffer de linha em stdin e sem buffer de stdout quando a saída for para um terminal. Se o seu awk formawk
, o que acontece no Ubuntu, você pode dar a-W interactive
opção de obter o mesmo comportamento de buffer.fonte