Mam skrypt bash, który wygląda następująco:
#!/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, aż do zakończenia polecenia, a następnie przejście do następnej jest bardzo czasochłonne, chcę przetworzyć na przykład 20 linii na raz, a po ich zakończeniu przetwarzanych jest kolejnych 20 linii.
Myślałem o wget LINK1 >/dev/null 2>&1 &
wysłaniu polecenia w tle i kontynuowaniu, ale jest tutaj 4000 linii, co oznacza, że będę mieć problemy z wydajnością, nie wspominając o ograniczeniu liczby procesów, które powinienem uruchomić w tym samym czasie, więc to nie jest dobre pomysł.
Jednym z rozwiązań, o których teraz myślę, jest sprawdzenie, czy jedno z poleceń nadal działa, na przykład po 20 wierszach 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ć i na końcu linii! Ale czuję, że to nie jest właściwy sposób, aby to zrobić.
Jak więc właściwie pogrupować każde 20 wierszy razem i poczekać, aż zakończą się, zanim przejdą do następnych 20 wierszy, ten skrypt jest generowany dynamicznie, więc mogę robić dowolną matematykę na nim podczas generowania, ale NIE musi to robić użyj wget, to był tylko przykład, więc każde rozwiązanie, które jest specyficzne dla wget, nic mi nie da.
wait
jest tutaj poprawną odpowiedzią, alewhile [ $(ps …
lepiej napisaćwhile pkill -0 $KEYWORD…
- używając proctools … czyli z uzasadnionych powodów, aby sprawdzić, czy proces o określonej nazwie nadal działa.Odpowiedzi:
Użyj
wait
wbudowanego:W powyższym przykładzie 4 procesy
process1
...process4
zostałyby uruchomione w tle, a powłoka poczekałaby na ich zakończenie przed uruchomieniem następnego zestawu.Z podręcznika GNU :
źródło
i=0; waitevery=4; for link in "${links[@]}"; do wget "$link" & (( i++%waitevery==0 )) && wait; done >/dev/null 2>&1
Zobacz równolegle . Jego składnia jest podobna do
xargs
, ale uruchamia polecenia równolegle.źródło
wait
, ponieważ zajmuje się rozpoczynaniem nowych zadań jako ukończonych starych, zamiast czekać na zakończenie całej partii przed rozpoczęciem następnej.cat list_of_links.txt | parallel -j 4 wget {}
co spowoduje utrzymanie czterechwget
s jednocześnie.parallel
.parallel --jobs 4 < list_of_commands.sh
, gdzie list_of_commands.sh to plik z pojedynczym poleceniem (np.wget LINK1
uwaga bez&
) w każdym wierszu. Może trzeba to zrobić,CTRL+Z
abg
potem pozostawić w tle.W rzeczywistości
xargs
może uruchamiać polecenia równolegle dla Ciebie. Jest do tego specjalna-P max_procs
opcja wiersza poleceń. Zobaczyćman xargs
.źródło
Możesz uruchomić 20 procesów i użyć polecenia:
Twój skrypt będzie czekał i będzie kontynuowany po zakończeniu wszystkich zadań w tle.
źródło