2013-11-15 4 views
2

У меня есть список с URL-адресами, которые мне нравится загружать с помощью CURL и выполнять некоторые операции с результатом с помощью скрипта bash. Поскольку это почти 100 тыс. Запросов, мне нравится запускать это параллельно. Я уже смотрел в GNU параллельно, но как я буду склеивать все вместе? Благодаря!Bashscript с параллельной операцией curl

bashscript:

while read URL; do 
curl -L -H "Accept: application/unixref+xml" $URL > temp.xml; 

YEAR=$(xmllint --xpath '//year' temp.xml); 
MONTH=$(xmllint --xpath '(//date/month)[1]' temp.xml); 

echo "$URL;$YEAR;$MONTH" >> results.csv; 

sed -i '1d' urls.txt; 

done < urls.txt; 
+0

Я бы не изменить 'urls.txt' внутри цикла при чтении из него. В лучшем случае это кажется ненужным. – chepner

ответ

2

Вы не должны быть изменения списка входного URL-адресов, как вы делаете каждый запрос HTTP. И наличие нескольких приложений, записывающих один и тот же выходной файл из разных процессов, скорее всего, закончится слезами.

Положите большинство ваших команд в отдельном скрипте (по имени, скажем, geturl.sh), который может быть вызван с URL в качестве параметра, и записывает свою линию вывода в стандартный вывод:

#!/usr/bin/env bash 
URL="${1}" 
curl -L -H "Accept: application/unixref+xml" "${URL}" > /tmp/$$.xml 
YEAR="$(xmllint --xpath '//year' /tmp/.xml)" 
MONTH="$(xmllint --xpath '(//date/month)[1]' /tmp/$$.xml)" 
rm -f /tmp/$$.xml 
echo "${URL};${YEAR};${MONTH}" 

Затем вызовите следующим образом (здесь мы позволим parallel объединить выходы из линии различных нитей по линии):

parallel --line-buffer geturl.sh <urls.txt> results.csv 
+0

Спасибо, это работает. Я сделал testrun для 100 URL-адресов, но похоже, что он не работает лучше, чем серийная версия. Может ли это быть проблемой? Я запущен CygWin – Thomas

+1

Попробуйте выполнить еще несколько заданий параллельно: 'parallel -j100' Также имейте в виду, что -line-буфер намного медленнее, чем по умолчанию (буфера полной работы за раз). –

+0

Спасибо, добавив -j100, улучшает характеристики. Есть ли альтернатива для -line-buffer? – Thomas