tr
похоже, буферизует свои данные, так что эта команда LongRunningCommand|tr \\n ,
начнет выводить данные только после накопления нескольких килобайт ввода от LongRunningCommand.
Есть ли способ принудительно tr
остановить эту буферизацию или любую другую команду, которая может заменить новые строки другим символом без буферизации?
PS Я уже попробовал первые два предложения от Отключить буферизацию в трубе без успеха.
stdbuf
к LongRunningCommand или к tr, или к обоим по-разному?stdbuf -o0 fping -aAq -r2 -g 10.30.0.1 10.30.0.255 2>/dev/null | stdbuf -i0 tr \\n ,
fping -q
говорит: «Не показывать результаты для каждого исследования, а только итоговое резюме», так что, возможно, в конце будет только одна длинная запись?tr
. Попробуйте|stdbuf -i0 -o0 tr ...
Ответы:
Команды обычно не буферизуют свой ввод. Они сделали бы
read()
для большого чанка, но при чтении из канала, если в конвейере не так много байтов,read()
системный вызов вернет столько символов, сколько есть, и приложение, как правило, будет работать с этим, если сможет ,Заметным исключением является то,
mawk
что будет продолжатьсяread()
до тех пор, пока входной буфер не будет заполнен.Приложения действительно буферизируют свои выходные данные (stdout). Обычное поведение состоит в том, что если вывод идет в tty, то буферизация будет построчной (то есть, она не начнет записывать в стандартный вывод, пока не получит полную строку для вывода, или заполненную блоком для очень длинная строка), в то время как для любого другого типа файла буферизация выполняется по блокам (то есть запись не начнется, пока не будет заполнен один блок для записи (что-то вроде 4 КБ / 8 КБ ... зависит от программного обеспечения и системы). )).
Таким образом, в вашем случае,
LongRunningCommand
вероятно, буферизует его вывод блоками (так как его вывод является конвейером, а не tty), и,tr
скорее всего, буферизует его вывод построчно, поскольку его выход, вероятно, является терминалом.Но, так как вы удаляете каждый символ новой строки из его вывода, он никогда не будет выводить строку, поэтому буферизация будет выполняться по блокам.
Так что здесь вы хотите отключить буферизацию для обоих
LongRunningCommand
иtr
. В системах GNU или FreeBSD:Обратите внимание, что если вы хотите соединить строки запятыми, лучше использовать этот подход
paste -sd , -
. Таким образом, вывод будет завершен символом новой строки (вам, вероятно, все равно потребуется отключить буферизацию).источник
sed
. извините, если это раздражало - но я не осознавал, что это были общие знания. Я думаю, что он использует LD_PRELOAD.Чтобы заменить новые строки на
","
, вы можете запуститьGNU awk (
gawk
) и Solarisnawk
будут работать с буферизацией строки на stdin и без буферизации stdout, когда вывод поступает на терминал. Если ваш awk естьmawk
, что происходит в Ubuntu, вы можете дать ему-W interactive
возможность получить такое же поведение буферизации.источник