Jak uruchomić wiele poleceń w tle w bashu w jednym wierszu?

169

Zwykle uruchamiam wiele poleceń z czymś takim:

sleep 2 && sleep 3

lub

sleep 2 ; sleep 3

ale co jeśli chcę uruchomić je oba w tle za pomocą jednego polecenia wiersza poleceń?

sleep 2 & && sleep 3 &

nie działa. I ani nie zastępując &&przy;

Czy jest na to sposób?

Palace Chan
źródło
8
Użyj, ()aby otoczyć polecenie.
nhahtdh
1
unix.stackexchange.com/questions/67006/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

318

Dokładnie jak chcesz, żeby działały? Jeśli chcesz, aby były uruchamiane w tle i działały sekwencyjnie , możesz zrobić coś takiego:

(sleep 2; sleep 3) &

Jeśli z drugiej strony chcesz, aby działały równolegle w tle, możesz zamiast tego zrobić to:

sleep 2 & sleep 3 &

Te dwie techniki można łączyć, na przykład:

(sleep 2; echo first finished) & (sleep 3; echo second finished) &

Bash będąc bashem, często istnieje wiele różnych technik wykonania tego samego zadania, chociaż czasami występują między nimi subtelne różnice.

Kitsune
źródło
20
To zwięzła, przemyślana odpowiedź, która „uczy człowieka łowić ryby” dla życia. Dzięki.
ambrus
2
Co się stanie, jeśli to zrobimy sleep 2 && sleep 3 &? Wypróbowałem to w bashu i wydaje się, że działa w ten sam sposób (próbowałem z echem).
Wajahat
@HakanBaba, Tak, rzeczywiście tworzy podpowłokę w tle.
Douwe van der Leest
3
@Wajahat, próbowałeś sleep 2 && echo "foo" && sleep 3 & echo "bar""? &&Operator informuje powłokę, aby wykonać polecenie przed nim, i tylko wtedy, który wykonuje polecenia bez jakiegokolwiek błędu powłoka wykonuje kolejną komendę. Różni się to zasadniczo od tego ;, że ;umożliwia wykonanie kolejnego polecenia niezależnie od statusu wyjścia poprzedniego polecenia, chyba że był to błąd krytyczny. &Mówi powłoce aby wykonać wszystkie polecenia „Connected” poprzedzający go w tle. „Połączony” oznacza tutaj, że polecenie jest częścią potoku ( |) lub operatora logicznego.
Douwe van der Leest
Of these list operators, ‘&&’ and ‘||’ have equal precedence, followed by ‘;’ and ‘&’, which have equal precedence.w podręczniku bash.
jinbeom hong
49

Musisz dodać kilka parenów w swojej ostatniej wersji -

(sleep 2 &) && (sleep 3 &)

lub to też działa -

(sleep 2 &) ; (sleep 3 &)
iagreen
źródło
Uwaga: gdy lista jest używana z &, jej kod zakończenia wynosi zawsze zero. Tak więc dwa powyższe przypadki robią to samo (powłoka wykonuje obie strony po kolei asynchronicznie ).
jinbeom hong
9

aby uruchomić wiele poleceń w tle, musisz dodać &koniec każdego polecenia. dawny: (command1 &) && (command2 &) && (command3 &)

saeed
źródło
5

Powyższe odpowiedzi używają nawiasów. Bash może również użyć szelek w podobnym celu:

{ sleep 2 && sleep 3; } &

Zwróć uwagę, że nawiasy klamrowe są bardziej wybredne pod względem składni - wymagana jest spacja po {, spacja przed }i końcowy średnik. W niektórych sytuacjach klamry są bardziej wydajne, ponieważ nie rozwidlają nowej podpowłoki. W tym przypadku nie wiem, czy to ma znaczenie.

Greg Reagle
źródło
1
O co chodzi { sleep 2; sleep 3; } &?
Kenny Evitt
4

To działa:

$(sleep 2 &) && sleep 3 &

Możesz także:

$(sleep 2 && sleep 3) &
higuaro
źródło
0

Ja też mam tę samą misję. Spróbuję (sleep2 ; fg )& sleep3 ; fg, to działa. A kiedy wstępnie podwoisz ctrl + c, oba procesy można zatrzymać.

dingyang wang
źródło
0

Możesz użyć podstawienia polecenia bash w $(command)następujący sposób:

$(command1 ; command2) &

Zauważ, że stdin i stdout są nadal połączone z procesem nadrzędnym i przekierowanie przynajmniej stdout może być trudne. Alternatywnie możesz połączyć polecenia w jeden wiersz, a następnie przekazać ciąg do bashpolecenia, aby odrodzić nowy proces, który zajmie się wykonaniem.

bash -c "command1 ; command2" & 

Jest to szczególnie przydatne w skrypcie bash, gdy musisz uruchomić wiele poleceń w tle.

Te dwie instrukcje powinny być równoważne. Atakujących proces tarło w obu przypadkach do obsługi poleceń (łańcuch poleceń) i tym &na koniec odłącza wykonania.

Tym razem możesz dodać &>/dev/nullprzed the &na końcu polecenia, aby przekierować przynajmniej wyjście standardowe i uniknąć wyjścia na standardowe wyjście procesu nadrzędnego. Coś jak:

bash -c "command1 ; command2" &>/dev/null &
Bemipefe
źródło
-1

Jeśli chcesz uruchamiać wiele poleceń sekwencyjnie , istnieje naprawdę prosta metoda, która działa wszędzie: Tworzenie pliku! Zaletą tej metody jest to, że jest czysta i prosta.

Najpierw utwórz plik o nazwie, np commands.sh. Następnie umieść tam swoje polecenia. Oto próbka:

commands.sh:

#!/system/bin/sh

sleep 3;
sleep 2;

OK, teraz jesteśmy na ostatnim etapie. Aby uruchamiać polecenia w tle (sekwencyjnie), po prostu uruchom:

$ sh commands.sh &
MAChitgarha
źródło