2017-03-02 5 views
1

Ich habe eine Möglichkeit implementiert, gleichzeitige Jobs in Bash zu haben, wie gesehen here.Bash gleichzeitige Jobs bleibt stecken

Ich bin durch eine Datei mit etwa 13000 Zeilen durchlaufen. Ich bin nur testen und Drucken jeder Zeile, wie zum Beispiel:

#!/bin/bash 
max_bg_procs(){ 
    if [[ $# -eq 0 ]] ; then 
     echo "Usage: max_bg_procs NUM_PROCS. Will wait until the number of background (&)" 
     echo "   bash processes (as determined by 'jobs -pr') falls below NUM_PROCS" 
     return 
    fi 
    local max_number=$((0 + ${1:-0})) 
    while true; do 
     local current_number=$(jobs -pr | wc -l) 
     if [[ $current_number -lt $max_number ]]; then 
       echo "success in if" 
       break 
     fi 
     echo "has to wait" 
     sleep 4 
    done 
} 

download_data(){ 
    echo "link #" $2 "["$1"]" 
} 

mapfile -t myArray < $1 

i=1 
for url in "${myArray[@]}" 
do 
    max_bg_procs 6 
    download_data $url $i & 
    ((i++)) 
done 
echo "finito!" 

ich auch andere Lösungen versucht haben, wie this und this, aber mein Problem ist persistent:

Bei einem „random“ gegeben Schritt normalerweise zwischen der 2000. und der 5000. Iteration bleibt es einfach stecken. Ich habe diese verschiedenen echo in der Mitte des Codes, um zu sehen, wo es stecken bleiben würde, aber es das letzte, was es druckt, ist die $url $i.

Ich habe den einfachen Test gemacht, um jede Parallelität zu entfernen und den Dateiinhalt einfach zu loopen: alles ging gut und es lief bis zum Ende.

So denke ich, dass ich eine Einschränkung der Parallelität vermisse, und ich frage mich, ob mir jemand helfen könnte, es herauszufinden.

Vielen Dank!

+2

http://mywiki.wooledge.org/ProcessManagement ist ein guter Anfang. –

+0

Warum haben Sie zusätzliche doppelte Anführungszeichen um '$ 1' in' echo "link #" $ 2 "[" $ 1 "]" ' – Inian

+2

BTW, gibt es eine Tonne von (nicht-zu-Ihrem-unmittelbaren-Problem) zitiert Bugs in dieser Code. Überlege, ob du deine Skripte über http://shellcheck.net/ ausführen möchtest, bevor du sie hier veröffentlichst. –

Antwort

3

Hier haben wir bis zu 6 parallele Bash-Prozesse, die download_data aufrufen, von denen jede bis zu 16 URLs pro Aufruf übergeben wird. Passen Sie nach Ihrer eigenen Abstimmung.

Beachten Sie, dass dies sowohl bash (für exportierte Funktionsunterstützung) als auch GNU xargs erwartet.

#!/usr/bin/env bash 
#    ^^^^- not /bin/sh 

download_data() { 
    echo "link #$2 [$1]" # TODO: replace this with a job that actually takes some time 
} 
export -f download_data 
<input.txt xargs -d $'\n' -P 6 -n 16 -- bash -c 'for arg; do download_data "$arg"; done' _ 
+0

Vielen Dank für die Hilfe. Dies scheint perfekt zu funktionieren. Es tut mir ein bisschen weh, einen Code zu benutzen, den ich nicht zu 80% verstehe, aber hoffentlich kann ich mir etwas Zeit nehmen, um über deine Lösung zu lesen. Glaubst du, dass das Problem, das ich zuvor hatte, mit deinem Kommentar über das "Warten" zusammenhängt? Noch einmal vielen Dank für Ihre Zeit und Hilfsbereitschaft. – Miguel

2

Benutzung von GNU Parallel es wie diese

cat input.txt | parallel echo link '\#{#} [{}]' 

{#} sieht = die Auftragsnummer
{} = das Argument

Es wird einen Prozess pro CPU laichen. Wenn Sie stattdessen 6 parallel Gebrauch -j wollen:

cat input.txt | parallel -j6 echo link '\#{#} [{}]' 

Wenn Sie eine Funktion bevorzugen laufen:

download_data(){ 
    echo "link #" $2 "["$1"]" 
} 
export -f download_data 
cat input.txt | parallel -j6 download_data {} {#} 
+0

Vielleicht bearbeiten Sie den [nutzlosen Gebrauch von 'Katze'] (http://www.iki.fi/era/unix/award.html) oder erklären Sie, wie Sie wissen, dass es eine schlechte Übung ist, aber es ist ein Platzhalter für etwas Nützlicheres. – tripleee

+0

Bitte lesen Sie http://oletange.blogspot.dk/2013/10/useless-use-of-cat.html und erklären Sie, warum Sie es für eine schlechte Übung halten. –

+0

Wir hatten diese Diskussion schon einmal, da Sie sich sicher erinnern können. Die Aufnahme dieses Links ist eine perfekte Lösung für das unmittelbare Problem, das immer noch besteht - ein Antipattern an Leser zu verüben, die es sonst nicht als einen identifizieren könnten. – tripleee

Verwandte Themen