Uruchamianie programów równolegle przy użyciu xargs

85

Obecnie posiadam aktualny skrypt.

#!/bin/bash
# script.sh

for i in {0..99}; do
   script-to-run.sh input/ output/ $i
done

Chciałbym uruchomić go równolegle za pomocą xargs. próbowałem

script.sh | xargs -P8

Ale powyższe czynności wykonywane były tylko raz na raz. Nie ma też szczęścia z -n8. Dodanie & na końcu wiersza do wykonania w skrypcie pętli for spowoduje próbę uruchomienia skryptu 99 razy na raz. Jak wykonać pętlę tylko 8 na raz, do 100 łącznie.

Olivier
źródło
To jest to, co początkowo chciałem zrobić, ale musiałem uciekać się do xargs, ponieważ pracuję w systemie Windows. Nie udało mi się uruchomić GNU Parallel działającego w systemie Windows
Olivier
Czy ten skrypt wywołuje sam siebie, czy po prostu pomyliłeś nazwy, kiedy zapytałeś tutaj?
Etan Reisner
Przepraszamy, to powinno wywołać inny skrypt. Naprawię to
Olivier
Odpowiedź na stackoverflow.com/questions/3321738/ ... jest tutaj istotna.
Etan Reisner

Odpowiedzi:

128

Ze strony podręcznika xargs:

Ta strona podręcznika opisuje wersję GNU xargs. xargs czyta elementy ze standardowego wejścia, oddzielone spacjami (które mogą być chronione podwójnymi lub pojedynczymi cudzysłowami lub odwrotnym ukośnikiem) lub znakami nowej linii i wykonuje polecenie (domyślnie / bin / echo) jeden lub więcej razy z dowolnymi argumentami początkowymi po nich według elementów odczytanych ze standardowego wejścia. Puste wiersze na standardowym wejściu są ignorowane.

Co oznacza, że ​​na Twój przykład xargsczeka i zbiera wszystkie dane wyjściowe ze skryptu, a następnie działa echo <that output>. Nie do końca takie przydatne, ani to, czego chciałeś.

-nArgumentem jest to, jak wiele elementów z wejściem do korzystania z każdego polecenia, które dostaje run (nic o sobie, o równoległości tutaj).

Aby zrobić, co chcesz xargs, musisz zrobić coś podobnego (nieprzetestowane):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/

Co się w ten sposób psuje.

  • printf %s\\n {0..99}- Drukuj po jednym numerze w wierszu od 0do 99.
  • Biegać xargs
    • przyjmowanie co najwyżej jednego argumentu na wiersz poleceń uruchamiania
    • i uruchamiaj do ośmiu procesów jednocześnie
Etan Reisner
źródło
7
Właściwie nie musisz umieszczać argumentów w oddzielnych wierszach; xargs podział na słowa. Więc echo {0..99} |działałoby równie dobrze. <<<{0..99}nie wydaje się działać; chociaż <<<wordjest udokumentowane jako słowo rozwijające nawiasy klamrowe, nie robi tego z żadną wersją bash, którą mam pod ręką.
rici
1
@rici Wygląda na błąd w dokumentacji, zwłaszcza że dokumentacja Here Documents nie wspomina o rozwijaniu nawiasów klamrowych (i nie zdarza się to również w szybkim teście), chociaż nie wspominają również o rozszerzaniu tyldy (co nie ma bo tak <<robi ). Rozszerzenia, które robią i nie występują w dokumentach i tutaj ciągach znaków są dla mnie trochę dziwne. <<<*shrug*
Etan Reisner
1
Jak można oddzielić wyniki z różnych przebiegów np. Za pomocą nowej linii?
nirvana-msu
3
Demo: time head -12 <(yes "1") | xargs -n1 -P4 sleepuruchomi 12 sleep 1poleceń, 4 równoległe. Polecenie zajmie 3 sekundy.
Walter A,
66

Z GNU Parallel zrobiłbyś:

parallel script-to-run.sh input/ output/ {} ::: {0..99}

Dodaj, -P8jeśli nie chcesz uruchamiać jednego zadania na rdzeń procesora.

Naprzeciw xargsbędzie zrobić dobry uczynek, nawet jeśli dane wejściowe zawierają przestrzeń,”lub" (nie w tym przypadku, chociaż). To również sprawia, czy wyjście z różnych miejsc pracy nie są mieszane ze sobą, więc jeśli użyć wyjścia jesteś gwarantuje, że nie dostaniesz pół kolejki z dwóch różnych zleceń.

GNU Parallel to ogólny program równoległy, który ułatwia równoległe uruchamianie zadań na tej samej maszynie lub na wielu maszynach, do których masz dostęp ssh.

Jeśli masz 32 różne zadania, które chcesz wykonać na 4 procesorach, prostym sposobem na zrównoleglenie jest uruchomienie 8 zadań na każdym procesorze:

Proste planowanie

Zamiast tego GNU Parallel tworzy nowy proces po zakończeniu - utrzymując aktywne procesory, a tym samym oszczędzając czas:

Planowanie równoległe GNU

Instalacja

Jeśli GNU Parallel nie jest spakowane do Twojej dystrybucji, możesz przeprowadzić instalację osobistą, która nie wymaga uprawnień administratora. Można to zrobić w 10 sekund, wykonując następujące czynności:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 67bd7bc7dc20aff99eb8f1266574dadb
12345678 67bd7bc7 dc20aff9 9eb8f126 6574dadb
$ md5sum install.sh | grep b7a15cdbb07fb6e11b0338577bc1780f
b7a15cdb b07fb6e1 1b033857 7bc1780f
$ sha512sum install.sh | grep 186000b62b66969d7506ca4f885e0c80e02a22444
6f25960b d4b90cf6 ba5b76de c1acdf39 f3d24249 72930394 a4164351 93a7668d
21ff9839 6f920be5 186000b6 2b66969d 7506ca4f 885e0c80 e02a2244 40e8a43f
$ bash install.sh

Aby zapoznać się z innymi opcjami instalacji, zobacz http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Ucz się więcej

Zobacz więcej przykładów: http://www.gnu.org/software/parallel/man.html

Obejrzyj filmy wprowadzające: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Przejdź przez samouczek: http://www.gnu.org/software/parallel/parallel_tutorial.html

Zapisz się na listę e-mailową, aby uzyskać pomoc: https://lists.gnu.org/mailman/listinfo/parallel

Ole Tange
źródło
19
To nie odpowiada na pytanie ani nie wskazuje, dlaczego xargs nie mogą osiągnąć tego samego.
张 实 唯
8
Głosuj w dół, ponieważ dla mnie xarg robi dokładnie to, co pokazuje drugie zdjęcie.
noonex
3
@noonex Czy wiesz, że nie wszyscy używają używanej przez Ciebie wersji xargs i że -P nie występuje we wszystkich wersjach xargs?
Ole Tange
19
Być może nie wszyscy zdają sobie sprawę, że tej odpowiedzi udziela autor paraleli GNU.
izkeros
1
Ocena negatywna z powodu wyraźnej reklamy oprogramowania, które nie działa poprawnie zgodnie z opisem przy pierwszych próbach, z powodu interaktywnego monitu, który psuje większość skryptów.
Daniel Sorichetti