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.


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

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.


4

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

for i in $(seq 1 10); do (./wait file$i &); done

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.