Wykonaj łączenie wielu poleceń Linuksa w jednym wierszu

329

Próbuję scalić wiele poleceń systemu Linux w jednym wierszu, aby wykonać operację wdrażania. Na przykład

cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install
d-man
źródło

Odpowiedzi:

717

Jeśli chcesz wykonać każde polecenie tylko wtedy, gdy poprzednie się powiodło, połącz je za pomocą &&operatora:

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

Jeśli jedno z poleceń nie powiedzie się, wszystkie pozostałe po nim polecenia nie zostaną wykonane.

Jeśli chcesz wykonać wszystkie polecenia niezależnie od tego, czy poprzednie nie powiodły się, rozdziel je średnikami:

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

W twoim przypadku myślę, że chcesz pierwszego przypadku, w którym wykonanie następnego polecenia zależy od powodzenia poprzedniego.

Możesz również umieścić wszystkie polecenia w skrypcie i wykonać je zamiast tego:

#! /bin/sh
cd /my_folder \
&& rm *.jar \
&& svn co path to repo \
&& mvn compile package install

(Ukośniki odwrotne na końcu wiersza służą temu, aby powłoka nie myślała, że ​​następny wiersz jest nowym poleceniem; jeśli pominiesz ukośniki odwrotne, musisz napisać całe polecenie w jednym wierszu).

Zapisz to na przykład w pliku i spraw myscript, aby był wykonywalny:

chmod +x myscript

Możesz teraz wykonać ten skrypt, podobnie jak inne programy na komputerze. Ale jeśli nie umieścisz go w katalogu wymienionym w PATHzmiennej środowiskowej (na przykład /usr/local/binlub w niektórych dystrybucjach Linuksa ~/bin), musisz podać ścieżkę do tego skryptu. Jeśli znajduje się w bieżącym katalogu, uruchom go za pomocą:

./myscript

Polecenia w skrypcie działają w taki sam sposób, jak polecenia w pierwszym przykładzie; następne polecenie jest wykonywane tylko wtedy, gdy poprzednie się powiodło. Aby bezwarunkowo wykonać wszystkie polecenia, po prostu wypisz każde polecenie w osobnym wierszu:

#! /bin/sh
cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install
Nikos C.
źródło
38
Dla przyszłych czytelników: Możesz również użyć ||zamiast średnika lub &&jeśli chcesz, aby następna komenda była wykonywana tylko w przypadku niepowodzenia ostatniej. Tak jak w tej próbie, a jeśli się nie powiedzie, spróbuj tego.
DeVadder
3
Hm, średniki nie zawsze działają. Np. ls >/dev/null & ; echo $!Wyzwala błąd.
Hi-Angel,
1
A co jeśli chcę uruchomić pierwsze polecenie w tle, a drugie na pierwszym planie ... Próbuję tego, tail -f my.log & && ./myscriptco nie działa ... proszę zasugerować.
OverrockSTAR
4
@Pareshkumar Za pomocą bash możesz: { tail -f my.log & } && ./myscriptJednak pamiętaj, że &&tutaj jest bezużyteczne, ponieważ pierwsze zadanie działa w tle, a zatem drugie zadanie nie może znać wyniku, ponieważ oba zadania rozpoczną się w tym samym czasie. Więc równie dobrze możesz po prostu napisać:{ tail -f my.log & }; ./myscript
Nikos C.
Co zrobić, jeśli potrzebuję sudouprawnień do uruchomienia jednego z poleceń? Czy powinienem umieścić sudona początku wszystkie polecenia, czy tylko w jednym, który tego potrzebuje? Jak mogę przekazać hasło do tego polecenia, aby zostało poprawnie wykonane?
Drubio,
46

Znalazłem to używając; oddzielanie poleceń działa tylko na pierwszym planie. np .:

cmd1; cmd2; cmd3 & - wykona się tylko cmd3w tle, podczas gdy cmd1 && cmd2 && cmd3 &- wykona cały łańcuch w tle JEŻELI nie będzie żadnych błędów.

Aby spełnić warunki bezwarunkowego wykonania, użycie nawiasu rozwiązuje to:

(cmd1; cmd2; cmd3) & - wykona łańcuch poleceń w tle, nawet jeśli jakikolwiek krok się nie powiedzie.

Dziekan
źródło
1
Czy końcowe znaki handlowe (i) w twoich przykładach były zamierzone? Jeśli tak, to po co?
Technophile,
5
@Technophile Aby uruchomić polecenie w tle
Oak Chantosa,
1
Jedna prosta, krótka i bezpośrednia odpowiedź, powinieneś częściej korzystać ze stron StackExchange Dean. Dzięki za wkład.
CPHPython
10

Możesz rozdzielić swoje polecenia za pomocą średnika:

cd /my_folder;rm *.jar;svn co path to repo;mvn compile package install

Czy o to ci chodziło?

andrux
źródło
3

Aby uruchomić je wszystkie naraz, możesz użyć klawisza linii rurociągu „|” tak:

$ cd /my_folder | rm *.jar | svn co path to repo | mvn compile package install
Kelly Poore
źródło
1
Potok służy do przekazywania danych wyjściowych polecenia do następnego polecenia jako danych wejściowych. Na przykład: X | Dane wyjściowe polecenia Y -> X będą działać jako dane wejściowe polecenia Y
Arpan Saini
2

Jeśli chcesz wykonać wszystkie polecenia, niezależnie od tego, czy poprzednie, czy nie, możesz użyć średnika (;), aby rozdzielić polecenia.

cd /my_folder; rm *.jar; svn co path to repo; mvn compile package install

Jeśli chcesz wykonać następne polecenie, tylko jeśli poprzednie polecenie się powiedzie, możesz użyć && do oddzielenia poleceń.

cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install

W twoim przypadku wykonywanie kolejnych poleceń wydaje się zależeć od poprzednich poleceń, więc skorzystaj z drugiego przykładu, tj. Użyj &&, aby dołączyć do poleceń.

Prabhu
źródło
1
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install
Mark Stevens
źródło
to nie to samo co skrypt OP, proszę wyjaśnić: jeśli polecenie nie powiedzie się, skrypt zostanie przerwany
Gilles Quenot
4
Dodatkowo możesz użyć cmd1 || cmd2separatora, jeśli chcesz cmd2wykonać tylko, jeśli cmd1zwrócisz powłoce niezerowy status, i możesz użyć, cmd1 ; cmd2jeśli chcesz uruchomić obie komendy bez względu na ich zwracany status.
Victor Sorokin,
@sputnick Powinno być, właśnie wkleiłem go i połączyłem polecenia z &&
Mark Stevens
3
@MarkStevens To lepsza implementacja, ale nie osiągnie takich samych rezultatów, jak gdyby polecenia były uruchamiane sekwencyjnie, myślę, że to właśnie oznaczało sputnick.
andrux,
1

Jaka jest użyteczność tylko jednego Ampersand? Dziś rano uruchomiłem program uruchamiający w panelu XFCE (w Manjaro + XFCE), aby jednocześnie uruchamiać 2 menedżerów haseł:

sh -c "keepassx && password-gorilla"
or
sh -c "keepassx; password-gorilla"

Ale to nie działa tak, jak chcę. IE, pierwsza aplikacja się uruchamia, ale druga uruchamia się dopiero po zamknięciu poprzedniej

Stwierdziłem jednak, że (tylko z jednym znakiem ampersand):

sh -c "keepassx & password-gorilla"

i działa tak, jak chcę teraz ...

Nettlebay AP
źródło
1
Ampersand działa podobnie jak terminator poleceń ;, z tym wyjątkiem, że umieszcza przed nim comman w tle, tzn. Powłoka nie zobaczy swojego wyniku.
Sergiy Kolodyazhnyy
-1

Możesz użyć jako następującego kodu;

cd /my_folder && \
rm *.jar && \
svn co path to repo && \
mvn compile package install

To działa...

Deniz Güzel
źródło
-1

Znajduję wiele odpowiedzi na tego rodzaju pytania wprowadzające w błąd

Zmodyfikowano z tego postu: https://www.webmasterworld.com/linux/3613813.htm

Poniższy kod utworzy okno bash i działa dokładnie jak okno bash. Mam nadzieję że to pomoże. Zbyt wiele błędnych / niedziałających odpowiedzi ...

            Process proc;
            try {
                //create a bash window
                proc = Runtime.getRuntime().exec("/bin/bash");
                if (proc != null) {
                       BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
                       PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
                       BufferedReader err = new BufferedReader(new InputStreamReader(
                       proc.getErrorStream()));
                       //input into the bash window
                       out.println("cd /my_folder");
                       out.println("rm *.jar");
                       out.println("svn co path to repo");
                       out.println("mvn compile package install");
                       out.println("exit");
                       String line;
                        System.out.println("----printing output-----");
                          while ((line = in.readLine()) != null) {
                             System.out.println(line);
                          }
                          while((line = err.readLine()) != null) {
                             //read errors
                          }
                          proc.waitFor();
                          in.close();
                          out.close();
                          err.close();
                          proc.destroy();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
wwjih123
źródło