2

Я очень озадачен тем, как использовать 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

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

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

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

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

$ seq 3 | parallel "echo {} | xxd"
00000000: 310a                                     1.
00000000: 320a                                     2.
00000000: 330a                                     3.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .