2

Согласно списку рассылки GNU Parallel, это не проблема GNU Parallel. Они предложили мне опубликовать мою проблему здесь.

Ошибка, которую я получаю, является ошибкой "сломанной трубы", но я чувствую, что должен сначала объяснить контекст моей проблемы и причины этой ошибки. Это происходит при попытке использовать любой скрипт bash, содержащий цикл while read в GNU Parallel.

У меня есть базовый сценарий Bash, как это:

#!/bin/bash
# linkcheck.sh

while read domain
do
host "$domain"
done

Предположим, что я хочу трубу в большом списке (скажем, 250 Мб).

cat urllist | ./linkcheck.sh

Выполнение команды хоста на 250 МБ URL-адресов выполняется довольно медленно. Чтобы ускорить процесс, я хочу разбить входные данные на куски перед передачей по конвейеру, а затем запустить несколько заданий параллельно. GNU Parallel способен сделать это.

cat urllist | parallel --pipe -j0 parallel ./linkcheck.sh {}

{} заменяется содержимым urllist построчно. Предположим, что моя системная установка по умолчанию способна выполнять 500ish заданий на экземпляр параллели. Чтобы обойти это ограничение, мы можем распараллелить сам параллель:

cat urllist | parallel -j10 --pipe parallel -j0 ./linkcheck.sh {}

Это запустит 5000'ых рабочих мест. К сожалению, это также приведет к ошибке "сломанная труба" (часто задаваемые вопросы по bash). Тем не менее, скрипт начинает работать, если я удаляю цикл while read и получаю ввод непосредственно из того, что подается в {}, например,

#!/bin/bash
# linkchecker.sh

domain="$1"
host "$1"

Почему он не будет работать с циклом чтения в то время как? Безопасно ли просто отключить сигнал SIGPIPE, чтобы остановить сообщение "сломанная труба", или это будет иметь побочные эффекты, такие как повреждение данных?

Спасибо за прочтение.

2 ответа2

1

Итак, сделал

cat urllist | parallel --pipe -j0 parallel ./linkcheck.sh {}

работать правильно?  Я полагаю, что частью вашей проблемы может быть то, что вы пропустили второй --pipe , как в

cat urllist | parallel -j10 --pipe parallel -j0 --pipe ./linkcheck.sh {}

 


Кстати, вам никогда не нужно говорить

cat one_file | some_command

Вы всегда можете изменить это на

some_command < one_file

приводя к одному меньшему количеству процесса (и одному меньшему количеству трубы).  (Может быть целесообразно / необходимо использовать cat когда у вас есть несколько входных файлов.)

0

Мне кажется, что ошибка может возникать из-за плохого состояния гонки из-за окна между разветвлением дочернего элемента для запуска другой копии linkcheck.sh, когда канал еще открыт, и когда дочерний процесс действительно пытается читать. В этом окне другая копия прочитала EOF, и канал закрылся.

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