Выполнить объединить несколько команд 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 Это запустить фоновую команду
Дуб Chantosa

1
Один простой, короткий и прямой ответ, вы должны чаще использовать сайты StackExchange, Дин. Спасибо за ваш вклад.
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, пожалуйста, объясните: если команда не выполняется, сценарий
прерывается

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

@sputnick Должно быть, я просто вставил его и соединил команды с &&
Марк Стивенс

3
@MarkStevens Это лучшая реализация, но она не даст таких же результатов, как если бы команды выполнялись последовательно, я думаю, что это имел в виду sputnick.
Андрукс

1

Какая польза только от одного амперсанда? Этим утром я сделал панель запуска на панели XFCE (в Manjaro + XFCE) для одновременного запуска 2 менеджеров паролей:

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

Но это не работает, как я хочу. IE, первое приложение запускается, а второе запускается только при закрытии предыдущего

Однако я обнаружил, что (только с одним амперсандом):

sh -c "keepassx & password-gorilla"

и это работает, как я хочу сейчас ...


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

-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.