Przetwarzanie skryptów Bash ograniczona liczba poleceń równolegle

Mam skrypt Basha, który wygląda tak:

#!/bin/bash
wget LINK1 >/dev/null 2>&1
wget LINK2 >/dev/null 2>&1
wget LINK3 >/dev/null 2>&1
wget LINK4 >/dev/null 2>&1
# ..
# ..
wget LINK4000 >/dev/null 2>&1

Ale przetwarzanie każdej linii do zakończenia polecenia, a następnie przejście do następnego jest bardzo czasochłonne, chcę przetworzyć na przykład 20 linii na raz, a kiedy już się skończą, przetwarzane są kolejne 20 linii.

Pomyślałem o wget LINK1 >/dev/null 2>&1 &, Aby wysłać polecenie w tło i kontynuować, ale jest tu 4000 linii, co oznacza, że będę miał problemy z wydajnością, nie wspominając o ograniczeniu liczby procesów, które powinienem wykonać zacznij w tym samym czasie, więc nie jest to dobry pomysł.

Jednym z rozwiązań, o którym teraz myślę, jest sprawdzenie, czy jedna z komend nadal działa, czy nie, na przykład po 20 liniach Mogę dodać tę pętlę:

while [  $(ps -ef | grep KEYWORD | grep -v grep | wc -l) -gt 0 ]; do
sleep 1
done

Oczywiście w tym przypadku będę musiał dołączyć & do końca linii! Ale czuję, że to nie jest dobry sposób.

Więc jak właściwie zgrupować każde 20 linii razem i czekać na ich zakończenie przed przejściem do następnych 20 linii, ten skrypt jest generowany dynamicznie, więc mogę robić na nim dowolną matematykę, ale nie musi używać wget, to był tylko przykład, więc każde rozwiązanie, które jest specyficzne dla wget, nie zrobi mi nic dobrego.

Author: tripleee, 2013-10-23

4 answers

Użyj wait wbudowanego:

process1 &
process2 &
process3 &
process4 &
wait
process5 &
process6 &
process7 &
process8 &
wait

Dla powyższego przykładu, 4 procesy process1 ... process4 zostanie uruchomiony w tle, a powłoka będzie czekać, aż zostaną ukończone przed uruchomieniem następnego zestawu.

Z instrukcji GNU :

wait [jobspec or pid ...]

Poczekaj, aż proces potomny określony przez pid każdego procesu lub specyfikację zadania jobspec zakończy działanie i zwróci status zakończenia ostatniego procesu dowództwo czekało. Jeśli podano specyfikację zadania, wszystkie procesy w zadaniu czekają na ciebie. Jeśli nie podano argumentów, wszystkie aktualnie aktywne potomstwo process are waited for, and The return status is zero. Jeżeli ani jobspec nor pid określa aktywny proces potomny powłoki, status powrotu to 127.

 290
Author: devnull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-24 17:17:56

Zobacz parallel . Jego składnia jest podobna do xargs, ale wykonuje polecenia równolegle.

 80
Author: choroba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 13:38:57

W rzeczywistości, xargs Może uruchamiać polecenia równolegle dla Ciebie. Istnieje do tego specjalna opcja -P max_procs wiersza poleceń. Zobacz man xargs.

 43
Author: Vader B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-27 06:41:12

Możesz uruchomić 20 procesów i użyć polecenia:

wait

Twój skrypt będzie czekać i kontynuować po zakończeniu wszystkich zadań w tle.

 6
Author: Binpix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-23 13:41:18