Баш Гну параллельной помощи - PullRequest
3 голосов
/ 26 июня 2011

это примерно http://en.wikipedia.org/wiki/Parallel_(software) и очень богатая справочная страница http://www.gnu.org/software/parallel/man.html

(for x in `cat list` ; do 
       do_something $x
   done) | process_output

заменено этим

 cat list | parallel do_something | process_output

Я пытаюсь реализовать это на этом

    while [ "$n" -gt 0 ]
        do          
        percentage=${"scale=2;(100-(($n / $end) * 100))"|bc -l}}
    #get url from line specified by n from file done1              
nextUrls=`sed -n "${n}p" < done1`
    echo -ne "${percentage}%  $n / $end urls saved going to line 1. current: $nextUrls\r"
#    function that gets links from the url
    getlinks $nextUrls
#save n
    echo $n > currentLine
    let "n--"
    let "end=`cat done1 |wc -l`"
    done

при чтении документации для параллельной GNU

я обнаружил, что функции не поддерживаются, поэтому getlink не будет использоваться параллельно

лучшее, что я нашел до сих пор -

seq 30 | parallel -n 4 --colsep '  ' echo {1} {2} {3} {4}

выводит

1 2 3 4 
5 6 7 8 
9 10 11 12 
13 14 15 16 
17 18 19 20 
21 22 23 24 
25 26 27 28 
29 30 

, в то время как упомянутый выше цикл должен идти следующим образом, если я прав

end=`cat done1 |wc -l`
seq $end -1 1 |  parallel -j+4 -k
#(all exept getlinks function goes here, but idk how? )|
# everytime it finishes do
 getlinks $nextUrls

Спасибо за помощь заранее

Ответы [ 5 ]

5 голосов
/ 27 июня 2011

Кажется, что вы хотите, это индикатор прогресса.Попробуйте:

cat done1 | parallel --eta wget

Если это не то, что вам нужно, посмотрите на sem (sem является псевдонимом для parallel --semaphore и обычно устанавливается с GNU Parallel):

for i in `ls *.log` ; do
  echo $i
  sem -j+0 gzip $i ";" echo done
done
sem --wait

В вашем случае это будет что-то вроде:

while [ "$n" -gt 0 ]
    do          
    percentage=${"scale=2;(100-(($n / $end) * 100))"|bc -l}}
    #get url from line specified by n from file done1
    nextUrls=`sed -n "${n}p" < done1`
    echo -ne "${percentage}%  $n / $end urls saved going to line 1. current: $nextUrls\r"
    #    function that gets links from the url
    THE_URL=`getlinks $nextUrls`
    sem -j10 wget $THE_URL
    #save n
    echo $n > currentLine
    let "n--"
    let "end=`cat done1 |wc -l`"
done
sem --wait
echo All done
1 голос
/ 26 июня 2011

Почему getlinks должна быть функцией?Возьмите функцию и преобразуйте ее в сценарий оболочки (он должен быть практически идентичен, за исключением того, что вам нужно экспортировать переменные среды, и вы, конечно, не сможете воздействовать на внешнюю среду без большой работы).

Конечно, вы не можете сохранить$ n в текущую строку, когда вы пытаетесь выполнить параллельно.Все файлы будут перезаписывать друг друга одновременно.

0 голосов
/ 15 августа 2011

Не совсем ясно, какова конечная цель вашего сценария. Если вы пытаетесь написать параллельный веб-сканер, вы можете использовать приведенный ниже шаблон в качестве шаблона.

#!/bin/bash

# E.g. http://gatt.org.yeslab.org/
URL=$1
# Stay inside the start dir
BASEURL=$(echo $URL | perl -pe 's:#.*::; s:(//.*/)[^/]*:$1:')
URLLIST=$(mktemp urllist.XXXX)
URLLIST2=$(mktemp urllist.XXXX)
SEEN=$(mktemp seen.XXXX)

# Spider to get the URLs
echo $URL >$URLLIST
cp $URLLIST $SEEN

while [ -s $URLLIST ] ; do
  cat $URLLIST |
    parallel lynx -listonly -image_links -dump {} \; wget -qm -l1 -Q1 {} \; echo Spidered: {} \>\&2 |
    perl -ne 's/#.*//; s/\s+\d+.\s(\S+)$/$1/ and do { $seen{$1}++ or print }' |
    grep -F $BASEURL |
    grep -v -x -F -f $SEEN | tee -a $SEEN > $URLLIST2
  mv $URLLIST2 $URLLIST
done

rm -f $URLLIST $URLLIST2 $SEEN
0 голосов
/ 27 июня 2011

пробовал sem

#!/bin/bash
func (){
echo 1
echo 2
}


for i in `seq 10`
do
sem -j10 func 
done
sem --wait
echo All done

вы получаете

ошибки

Can't exec "func": No such file or directory at /usr/share/perl/5.10/IPC/Open3.p
m line 168.
open3: exec of func  failed at /usr/local/bin/sem line 3168  
0 голосов
/ 27 июня 2011

Я думал о том, чтобы сделать что-то более похожее на это, если не на параллель, или на что-то другое, потому что параллель не поддерживает функции ака http://www.gnu.org/software/parallel/man.html#aliases_and_functions_do_not_work

getlinks(){
if [ -n "$1" ]
then
    lynx -image_links -dump "$1" > src
    grep -i ".jpg" < src > links1
    grep -i "http"  < links1 >links  
    sed -e  's/.*\(http\)/http/g'  < links >> done1
    sort -f done1 > done2
    uniq done2 > done1
    rm -rf links1 links src done2 
fi
}
func(){
 percentage=${"scale=2;(100-(($1 / $end) * 100))"|bc -l}}
        #get url from line specified by n from file done1
        nextUrls=`sed -n "${$1}p" < done1`
        echo -ne "${percentage}%  $n / $end urls saved going to line 1. current: $nextUrls\r"
        #    function that gets links from the url
        getlinks $nextUrls
        #save n
        echo $1 > currentLine
        let "$1--"
        let "end=`cat done1 |wc -l`"
}
while [ "$n" -gt 0 ]
    do          
   sem -j10 func $n
done
sem --wait
echo All done

Мой сценарий стал действительно сложным, и я не хочу делать функцию недоступной из-за чего-то, я не уверен, что это можно сделать таким образом, я могу получить ссылки с полным интернет-трафиком, это займет меньше времени

...