Виконати об'єднання декількох команд Linux в одному рядку


329

Я намагаюся об'єднати кілька команд Linux в один рядок, щоб виконати операцію розгортання. Наприклад

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

Відповіді:


717

Якщо ви хочете виконати кожну команду лише в тому випадку, якщо попередня була успішна, комбінуйте їх за допомогою &&оператора:

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

Якщо одна з команд відмовиться, всі інші команди, що слідують за нею, не виконуватимуться.

Якщо ви хочете виконати всі команди незалежно від того, попередні не вдалися чи ні, розділіть їх крапкою з комою:

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

У вашому випадку я думаю, ви хочете перший випадок, коли виконання наступної команди залежить від успіху попередньої.

Ви також можете помістити всі команди в сценарій і виконати його замість:

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

(Зворотні косої риски в кінці рядка є для того, щоб оболонка не думала, що наступний рядок - це нова команда; якщо ви опустите косої риски, вам потрібно буде записати всю команду в один рядок.)

Збережіть це, наприклад myscript, у файлі та зробіть його виконуваним:

chmod +x myscript

Тепер ви можете виконати цей скрипт, як і інші програми на машині. Але якщо ви не розмістите його в каталозі, переліченому в PATHзмінній вашого середовища (наприклад /usr/local/bin, або в деяких дистрибутивах Linux ~/bin), вам потрібно буде вказати шлях до цього сценарію. Якщо він знаходиться в поточному каталозі, виконайте його за допомогою:

./myscript

Команди в скрипті працюють так само, як команди в першому прикладі; наступна команда виконується лише в тому випадку, якщо попередня була успішна. Для безумовного виконання всіх команд просто перелічіть кожну команду у своєму рядку:

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

38
Для майбутніх читачів: Ви також можете використовувати ||крапку з комою або, &&якщо ви хочете, щоб наступна команда була виконана лише в тому випадку, коли остання не вдалася. Як і в цьому, і якщо це не вдалося, спробуйте.
DeVadder

3
Гм, крапки з комою не завжди працюють. Наприклад, ls >/dev/null & ; echo $!ініціює помилку.
Привіт-Ангел

1
А що робити, якщо я хочу запустити першу команду у фоновому режимі та іншу на передньому плані .. Я намагаюся цю tail -f my.log & && ./myscriptфункцію не працювати .. будь ласка, підкажіть.
OverrockSTAR

4
@Pareshkumar З bash ви можете зробити: { tail -f my.log & } && ./myscriptОднак зауважте, що &&тут марно, оскільки перше завдання працює у фоновому режимі, і, отже, друге завдання не може знати результат, оскільки обидва завдання розпочнуться одночасно. Тож ви можете просто написати:{ tail -f my.log & }; ./myscript
Нікос К.

Що робити, якщо мені потрібні sudoдозволи для запуску однієї з команд? Чи повинен я ставити sudoна початку всіх команд чи просто в тій, яка потрібна? Як я можу передати пароль цій команді, щоб вона була належним чином виконана?
Друбіо

46

Я виявив, що використовуючи; для розділення команд працює лише на передньому плані. наприклад:

cmd1; cmd2; cmd3 & - буде виконуватися лише cmd3у фоновому режимі, тоді як cmd1 && cmd2 && cmd3 &- буде виконувати весь ланцюг у фоновому режимі, якщо помилок немає.

Для забезпечення безумовного виконання за допомогою дужок вирішується це:

(cmd1; cmd2; cmd3) & - виконає ланцюжок команд на задньому плані, навіть якщо якийсь крок не вдасться.


1
Чи був заглиблений амперсанд (&) у ваших прикладах навмисним? Якщо так, для чого це?
Технофіл

5
@Technophile Це виконати фонову команду
Oak Chantosa

1
Один простий, короткий і прямий відповідь, ви повинні використовувати сайти StackExchange частіше Dean. Дякуємо за ваш внесок
CPHPython

10

Ви можете відокремити команди за допомогою крапки з комою:

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

Це ви мали на увазі?


3

Щоб запустити їх усі одразу, ви можете скористатися клавішею трубопроводу "|" так:

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

1
Конвеєр використовується для передачі результату вашої команди наступній команді як вхід. Наприклад: X | Y -> X командний вихід буде працювати як вхід для команди Y
Arpan Saini

2

Якщо ви хочете виконати всі команди, незалежно від того, виконує чи попередня, ви можете використовувати крапку з комою (;) для розділення команд.

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

Якщо ви хочете виконати наступну команду, лише якщо попередня команда успішна, ви можете використовувати && для розділення команд.

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

У вашому випадку виконання послідовних команд, схоже, залежить від попередніх команд, тому використовуйте другий приклад, тобто використовуйте &&, щоб приєднатися до команд.


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

це не те саме, що сценарій OP, будь ласка, поясніть: якщо команда aa не вдасться, сценарій
скасовується

4
Крім того, ви можете використовувати cmd1 || cmd2роздільник, якщо вам потрібно cmd2виконати лише те, що cmd1повернувся ненульовий статус до оболонки, а ви можете використовувати, cmd1 ; cmd2якщо ви хочете виконати обидві команди незалежно від їх стану повернення.
Віктор Сорокін

@sputnick Це повинно бути, я щойно вставив його і з'єднав команди з &&
Марк Стівенс

3
@MarkStevens Це краща реалізація, але вона не досягне тих же результатів, як якщо б команди виконувалися послідовно, я думаю, що це означало Sputnick.
andrux

1

У чому полягає корисність єдиного Ampersand? Сьогодні вранці я зробив пускову панель на панелі XFCE (у Manjaro + XFCE), щоб запустити 2 менеджери паролів одночасно:

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

Але це працює не так, як я хочу. IE, перша програма запускається, але друга запускається лише тоді, коли попередня закрита

Однак я виявив, що (лише з однією амперсандою):

sh -c "keepassx & password-gorilla"

і працює так, як я хочу зараз ...


1
Ampersand виконує функцію аналогічного термінатора ;, за винятком того, що це ставить comman перед ним у фоновому режимі, тобто оболонка не побачить його вихід.
Сергій Колодяжний

-1

Ви можете використовувати як наступний код;

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

Це працює...


-1

Я вважаю, що багато відповідей на таке питання є оманливим

Змінено з цього допису: https://www.webmasterworld.com/linux/3613813.htm

Наступний код створить вікно bash і працює точно як вікно bash. Сподіваюсь, це допомагає. Занадто багато неправильних / непрацюючих відповідей там ...

            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();
            }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.