Uruchom to samo polecenie wiele razy w tle

14

Jak można uruchamiać wiele poleceń i wykonywać je w tle za pomocą bash?

Na przykład:

$ for i in {1..10}; do wait file$i &; done

gdzie czekanie jest niestandardowym plikiem binarnym.

W tej chwili pojawia się błąd:

syntax error near unexpected token `;'

podczas uruchamiania powyższego polecenia.

Po umieszczeniu w tle polecenia powinny działać równolegle.

Sebi
źródło
1
Przypominam, że nie masz na myśli: nohuppozwalając ci wykonać polecenie w tle
Dave Hamilton
3
Występujący błąd jest spowodowany &i ;oba są „terminatorami poleceń”. Nie musisz używać obu: for ...; do wait $arg & donebędzie działać.
glenn jackman
@glenn jackman. Tak, faktycznie wypróbowałem to po opublikowaniu pytania. Oba nie są potrzebne; oraz &
Sebi
3
Dla przyszłych czytelników link do dokumentacji : „Lista jest sekwencją jednego lub więcej potoków oddzielonych jednym z operatorów”; ”,„ & ”,„ && ”lub„ || ”i opcjonalnie zakończoną przez jeden z „;”, „&” lub nowego wiersza. ” (moje podkreślenie)
glenn jackman
stackoverflow.com/q/14753491/560648
Lekkość ściga się na orbicie

Odpowiedzi:

21

&, Tak jak ;jest to lista terminator operator. Mają tę samą składnię i mogą być używane zamiennie (w zależności od tego, co chcesz zrobić). Oznacza to, że nie chcesz ani nie potrzebujesz command1 &; command2, wszystko czego potrzebujesz to command1 & command2.

W twoim przykładzie możesz po prostu napisać:

for i in {1..10}; do wait file$i & done

a każde waitpolecenie zostanie uruchomione w tle, a pętla natychmiast przejdzie do następnego.

terdon
źródło
4

Ze względu na kompatybilność użyj formy posiksowej zamiast rozszerzenia:

for i in $(seq 1 10); do (./wait file$i &); done
Marc
źródło
1
Zauważ, że seqnie jest to polecenie POSIX i ogólnie można go znaleźć tylko w systemach GNU. Zachowanie lub $(...)(i $i) zależy od bieżącej wartości $IFS. Należy również pamiętać, że robiąc (cmd &), cmdbędzie dzieckiem podpowłoce, więc nie będą mogli poczekać i uzyskać jego status wyjścia na przykład.
Stéphane Chazelas
2

Możesz pogrupować polecenia i umieścić zgrupowane polecenia w tle. Lubić :

$ for i in {1..10}; do ((wait file$i)&); done
labirynty
źródło
Nie ma potrzeby, aby korzystać z wewnętrznych nawiasów ...
MARC
wystarczy użyć wewnętrznych nawiasów, jeśli chcesz umieścić w tle wiele poleceń, zgodnie z pytaniem w pytaniu. Like ((spać 1; poczekaj plik $ i) &);
mazs
2

Czy Twój plik binarny naprawdę ma nazwę wait? Nie polecam tego robić, ponieważ waitjest to wbudowana powłoka.

Uważam, że bash nie analizuje dobrze pętli jednowierszowej, która uruchamia procesy w tle. Sugeruję zmianę kodu na:

$ for i in {1..10}; do ./wait file$i & echo "Running 'wait' using PID=$!..."; done
Anderson Medeiros Gomes
źródło