GNU "Параллельный --pipe" не обрабатывает стандартный ввод по строкам

478
ThorSummoner

Я очень озадачен тем, как использовать GNU параллельно для передачи стандартного ввода в команду задания.

У меня есть то, что я представлял себе как очень распространенный вариант использования. У меня есть процесс, xxdкоторый делает что-то с stdin и выводит на stdout. У меня есть некоторый способ генерировать или получать работу из другого стандартного потока, например seq 3, и я могу объединить их и сделать импровизированный электроинструмент, например, так:

$ seq 3 | while read line; do echo $line | xxd; done 00000000: 310a 1. 00000000: 320a 2. 00000000: 330a 3. 

Отлично. Мы можем ясно видеть, что каждый вызов xxdполучает одну строку, и добавляется завершающий символ новой строки.

Вот что parallelделает трубопровод :

$ seq 3 | parallel --pipe --recend="\n" -L 1 xxd ...  00000000: 310a 320a 330a 1.2.3. 

parallel --pipeберет все stdin и отправляет их на один вызов, xxdкоторый смущает меня, потому что все документированные параметры и их значения по умолчанию, кажется, противоречат этому поведению: --recend="\n"(по умолчанию) разделяет задания по новой -L 1строке, (по умолчанию) отправляет максимум одну строку команде ,

Нулевые разделители имеют ту же проблему. Они также переданы через дословно:

seq 3 | tr '\n' '\0' | parallel --null --pipe xxd ...  00000000: 3100 3200 3300 1.2.3. 

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

2

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

2
Ole Tange

Вы НАСТОЛЬКО близки. -Lустанавливает размер записи (в строках), но не определяет количество отправляемых записей. Это контролируется -N. По умолчанию --recendэто \nтак, что не нужно. По умолчанию -L1, так что это не нужно.

seq 3 | parallel --pipe -N 1 xxd 
1
ThorSummoner

Примечание: это мой оригинальный обходной путь. Это довольно некрасиво и уступает принятому ответу . Я оставляю это целым по образовательным причинам все же.

Хитрость заключается в том, чтобы не использовать режим конвейера и использовать echo (или аналогичный метод) для преобразования аргументов execve в стандартный вывод для каждого задания:

$ seq 3 | parallel "echo {} | xxd" 00000000: 310a 1. 00000000: 320a 2. 00000000: 330a 3. 
Хорошая работа. Проголосовал за обмен знаниями таким образом. Kamil Maciorowski 6 лет назад 0

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