выполнить команду для каждой строки стандартного ввода немедленно?

819
VasyaNovikov

Как выполнить команду для каждой строки stdinсразу?

Пример :

(echo abc; sleep 10; echo def;) | ??? 

xargsИнструмент не делает работу, потому что он блокирует до тех пор, пока не увидит все данные (ждет, пока стандартный вывод, чтобы закрыть). Тем не менее, я должен выполнять команды сразу же, как только становятся доступными новые строки.

3
http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe может быть интересно прочитать. Hennes 8 лет назад 1
@Hennes Спасибо. К сожалению, это не помогает. Проблема не в канале, а в том, как работает `xargs` (он ждет / блокирует, пока не увидит все входные данные). VasyaNovikov 8 лет назад 0
Так что не используйте xargs. Передайте небуферизованный вывод через канал, а на другом конце канала используйте сценарий оболочки для чтения строк до EOF. Hennes 8 лет назад 1
@Hennes Я ищу утилиту командной строки, которая сделала бы это для меня. VasyaNovikov 8 лет назад 0
@Hennes Я написал пример ответа, чтобы понять идею ваших комментариев. VasyaNovikov 8 лет назад 1

2 ответа на вопрос

2
Ole Tange

Используя GNU Parallel:

(echo abc; sleep 10; echo def;sleep 10; echo def;)|parallel -uj1 

-u требуется, чтобы получить вывод немедленно. Без команды будет работать, но вывод будет напечатан только позже.

-j1 заставляет запустить один рабочий участок. Если оставить его, GNU Parallel прочитает n заданий перед запуском, где n = количество ядер.

Вау, это сработало! Я пытался `параллельно -u эхо`, но, как вы сказали,` -j1` был необходим. VasyaNovikov 8 лет назад 0
1
VasyaNovikov

Используя скрипт оболочки, предложенный @Hennes:

long_running_command | ( while read -r LINE; do echo $LINE; command_to_execute "$LINE"; done; ) 

Похожие вопросы