Jak mogę uruchomić wiele poleceń, które mają i w jednym wierszu poleceń?

8

Napotkałem problem z bólem głowy.

Chcę wykonywać polecenia mulitple w tle, więc chcę je uruchomić w bashu jeden po drugim. Łatwo jest uruchomić jedno polecenie w powłoce linuxowej w tle, tak jak poniżej:

myCommand &

Łatwo też uruchamiać wiele poleceń, tak jak poniżej:

myCommand1 && myCommand2

lub

myCommand1 ; myCommand2

Ale jeśli chcę uruchomić wiele poleceń w tle, spróbowałem następującego formatu polecenia, ale nie udało się:

myCommand1 & && myCommand2 &

lub

myCommand1 & ; myCommand2 &

Oba formaty zawodzą. Jak mogę uruchomić wiele poleceń, które mają & w jednym wierszu poleceń?

    
zadawane Clock ZHONG 29.12.2017, 04:38
źródło

2 odpowiedzi

14

Użyj ().

Jeśli chcesz uruchomić je sekwencyjnie:

(myCommand1; myCommand2) &

lub

(myCommand1 &) && (myCommand2 &)

Jeśli chcesz, aby działały równolegle:

myCommand1 & myCommand2 &

W bashu możesz również użyć tego (spacja za {i; są obowiązkowe):

{ myCommand1 && myCommand2; } &
    
odpowiedział Rinzwind 29.12.2017, 09:59
źródło
14

Przypuszczam, że chcesz tego:

myCommand1 & myCommand2 &

To uruchamia myCommand1 i wysyła go do tła, po którym następuje znak ampersand, a następnie natychmiast uruchamia myCommand2 i wysyła to również do tła, zwalniając ponownie powłokę.

Listy

Aby lepiej zrozumieć, możesz zastąpić potok poleceniem .

  

Lista jest sekwencją jednego lub kilku potoków oddzielonych jednym z nich   operatory , , & amp; , & amp; & amp; lub || i opcjonalnie zakończone przez jeden z   ; , & amp; lub .

     

Jeśli polecenie zostanie zakończone przez operatora sterującego & amp; , znak   powłoka wykonuje polecenie w tle w podpowłoce. The   powłoka nie czeka na zakończenie polecenia, a   status powrotu wynosi 0. Komendy rozdzielone przez ; są wykonywane   sekwencyjnie; powłoka czeka na zakończenie każdego polecenia   skręcać. Status powrotu jest stanem wyjścia ostatniego polecenia   wykonane.

     

Listy AND i OR są sekwencjami oddzielonymi jednym lub większą liczbą potoków   odpowiednio przez operatorów & amp; i || .
Źródło: man bash

Podzielmy to na przykłady. Możesz zbudować listę, łącząc polecenia i oddzielając je jednym z następujących: ; & && || :

command1 ; command2  # runs sequentially
command1 && command2 # runs sequentially, runs command2 only if command1 succeeds
command1 || command2 # runs sequentially, runs command2 only if command1 fails
command1 & command2  # runs simultaneously

Możesz zakończyć listę z jednym z następujących: ; & <newline> .
Zwykle wykonuje się polecenie lub listę, naciskając Enter , co równa się <newline> . Średnik ; służy temu samemu celowi, szczególnie w skryptach. Ampersand & jednak uruchamia polecenie (polecenia) w podpowłoce w tle, natychmiast zwalniając powłokę.

Możesz użyć okrągłego () lub nawiasów klamrowych {} do dalszych list grup, z tą różnicą, że nawiasy okrągłe odradzają podpowłokę, a nawiasy klamrowe nie. Kręcone nawiasy wymagają spacji po pierwszym i średniku lub znaku nowej linii przed nawiasem zamykającym. Na przykład:

# if c1 succeeds start a shell in the background
# and run c2 and c3 sequentially inside it
c1 && ( c2 ; c3 ) & 
# run c1 and if it succeeds c2 sequentially as a group command
# if c1 or c2 fail run c3 in the background
{ c1 && c2 ;} || c3 &

Może to być dość skomplikowane, jeśli nie masz pewności, że używasz true i false do sprawdzenia, czy konstrukcja działa zgodnie z oczekiwaniami:

$ { true && true ;} || echo 2
$ { true && false ;} || echo 2
2

Kontrola zadań

Polecenie jobs wyświetla listę zadań w tle, które są uruchomione lub zostały ostatnio zakończone w bieżącej powłoce. Istnieje wiele skrótów klawiaturowych i poleceń do sterowania zadaniami:

  • Ctrl + Z wpisuje znak zawieszenie , który powoduje zatrzymanie procesu aktualnie uruchomionego na pierwszym planie, nie jest zakończony, ale pozostaje w jobs lista
  • Ctrl + Y wpisuje znak opóźnionego zawieszania , który powoduje zatrzymanie procesu aktualnie uruchomionego na pierwszym planie, gdy próbuje odczytać dane wejściowe z terminala
  • fg = % przenosi proces na pierwszy plan, jeśli jest to konieczne, możesz określić proces w następujący sposób:

     %       # last process in the jobs list
     %1      # 1st process in the jobs list
     %abc    # process beginning with the string “abc”
     %?abc   # process containing the string “abc” anywhere
    
  • bg = %& przenosi proces do tła, jeśli jest to konieczne:

     %&      # last process in the jobs list
     %1&     # 1st process in the jobs list
     %abc&   # process beginning with the string “abc”
     %?abc&  # process containing the string “abc” anywhere
    
  • wait czeka na zakończenie procesu w tle i zwraca status zakończenia:

     wait %1 # 1st process in the jobs list
    

    Wyobraź sobie, że rozpocząłeś długi proces ( jobs ujawnia jego numer 3), a następnie zdajesz sobie sprawę, że chcesz zawiesić komputer po zakończeniu, plus echo wiadomość, jeśli proces się nie powiódł:

     wait %3 || echo failed ; systemctl suspend
    
odpowiedział dessert 29.12.2017, 09:42
źródło

Przeczytaj inne pytania na temat tagów