Сценарий Bash, в то время как чтение цикла вызывает ошибку «сломанный канал» при запуске с GNU Parallel
1962
Joe White
Согласно списку рассылки 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 способен сделать это.
{} заменяется содержимым urllist построчно. Предположим, что моя системная установка по умолчанию способна выполнять 500ish заданий на экземпляр параллели. Чтобы обойти это ограничение, мы можем распараллелить сам параллель:
Это запустит 5000'ых рабочих мест. К сожалению, это также приведет к ошибке «сломанная труба» (часто задаваемые вопросы по bash) . Тем не менее, сценарий начинает работать, если я удаляю цикл while read и беру ввод непосредственно из того, что подается в {}, например,
Почему он не будет работать с циклом чтения в то время как? Безопасно ли просто отключить сигнал SIGPIPE, чтобы остановить сообщение «сломанная труба», или это будет иметь побочные эффекты, такие как повреждение данных?
Спасибо за прочтение.
2 ответа на вопрос
1
Scott
Итак, сделал
кошачий урлист | параллель --pipe -j0 параллель ./linkcheck.sh {}
работать правильно? Я полагаю, что частью вашей проблемы может быть то, что вы не учли второе --pipe, как в
кошачий урлист | параллель -j10 --pipe параллель -j0 --pipe ./linkcheck.sh {}
Кстати, вам никогда не нужно говорить
кот one_file | some_command
Вы всегда можете изменить это на
some_command < one_file
в результате на один процесс меньше (и на одну трубу меньше). (Это может быть целесообразно / необходимо использовать, catкогда у вас есть несколько входных файлов.)
Благодарю. Отсутствие второго - трубы было моей проблемой. Я мог бы поклясться, что уже пробовал это, но, очевидно, нет.
Joe White 12 лет назад
0
@Joe: Кроме того, если вы используете `--pipe`, я подозреваю, что` {} `не нужен / игнорируется.
Scott 12 лет назад
1
0
Nicole Hamilton
Мне кажется, что ошибка может возникать из-за плохого состояния гонки из-за окна между разветвлением дочернего элемента для запуска другой копии linkcheck.sh, когда канал еще открыт, и когда дочерний процесс действительно пытается читать. В этом окне другая копия прочитала EOF, и канал закрылся.
Да, я думаю, что вы правы. Спасибо за ваш вклад.
Joe White 12 лет назад
0