Executar combinar vários comandos do Linux em uma linha

329

Estou tentando mesclar vários comandos linux em uma linha para executar a operação de implantação. Por exemplo

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

Respostas:

717

Se você deseja executar cada comando apenas se o anterior tiver sido bem-sucedido, combine-os usando o &&operador:

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

Se um dos comandos falhar, todos os outros comandos seguintes não serão executados.

Se você deseja executar todos os comandos, independentemente de os anteriores terem falhado ou não, separe-os com ponto e vírgula:

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

No seu caso, acho que você quer o primeiro caso em que a execução do próximo comando depende do sucesso do anterior.

Você também pode colocar todos os comandos em um script e executá-lo:

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

(As barras invertidas no final da linha existem para impedir que o shell pense que a próxima linha é um novo comando; se você omitir as barras invertidas, será necessário gravar o comando inteiro em uma única linha.)

Salve isso em um arquivo, por exemplo myscript, e torne-o executável:

chmod +x myscript

Agora você pode executar esse script como outros programas na máquina. Mas se você não o colocar dentro de um diretório listado em sua PATHvariável de ambiente (por exemplo /usr/local/bin, ou em algumas distribuições Linux ~/bin), será necessário especificar o caminho para esse script. Se estiver no diretório atual, você o executará com:

./myscript

Os comandos no script funcionam da mesma maneira que os comandos no primeiro exemplo; o próximo comando somente será executado se o anterior tiver êxito. Para execução incondicional de todos os comandos, basta listar cada comando em sua própria linha:

#! /bin/sh
cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install
Nikos C.
fonte
38
Para futuros leitores: Você também pode usar em ||vez de ponto-e-vírgula ou &&se desejar que o próximo comando seja executado apenas se o último falhar. Como em tentar isso, e se falhar, tente isso.
DeVadder
3
Hm, ponto e vírgula nem sempre funciona. Por exemplo, ls >/dev/null & ; echo $!dispara um erro.
Hi-Angel
1
E se eu quiser executar o primeiro comando em segundo plano e outro em primeiro plano .. Estou tentando isso tail -f my.log & && ./myscriptque não está funcionando .. por favor sugira.
precisa saber é o seguinte
4
@Pareshkumar Com o bash, você pode: { tail -f my.log & } && ./myscriptNo entanto, observe que &&aqui é inútil, pois o primeiro trabalho é executado em segundo plano e, portanto, o segundo trabalho não pode saber o resultado, pois os dois trabalhos serão iniciados ao mesmo tempo. Então é melhor você escrever:{ tail -f my.log & }; ./myscript
Nikos C.
E se eu precisar de sudopermissões para executar um dos comandos? Devo colocar o sudono início de todos os comandos ou apenas o que precisa? Como posso passar a senha para esse comando para que seja executada corretamente?
Drubio 11/01/19
46

Eu descobri isso usando; separar comandos só funciona em primeiro plano. por exemplo :

cmd1; cmd2; cmd3 & - executará apenas cmd3em segundo plano, enquanto cmd1 && cmd2 && cmd3 &- executará toda a cadeia em segundo plano, se não houver erros.

Para atender à execução incondicional, o uso de parênteses resolve isso:

(cmd1; cmd2; cmd3) & - executará a cadeia de comandos em segundo plano, mesmo se alguma etapa falhar.

reitor
fonte
1
O e comercial final (&) nos seus exemplos foi intencional? Se sim, para que serve?
Technophile
5
@Technophile É para executar um comando de fundo
Oak Chantosa
1
Uma resposta simples, curta e direta, você deve usar os sites StackExchange com mais frequência, Dean. Obrigado pela sua contribuição.
precisa saber é o seguinte
10

Você pode separar seus comandos usando um ponto e vírgula:

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

Foi isso que você quis dizer?

andrux
fonte
3

Para executá-los todos de uma vez, você pode usar a tecla da linha do tubo "|" igual a:

$ cd /my_folder | rm *.jar | svn co path to repo | mvn compile package install
Kelly Poore
fonte
1
O pipeline está sendo usado para fornecer a saída do seu comando para o próximo comando como uma entrada. Por exemplo: X | Y - saída> X comando irá funcionar como entrada para o comando Y
Arpan Saini
2

Se você deseja executar todos os comandos, independentemente de o anterior executar ou não, você pode usar ponto-e-vírgula (;) para separar os comandos.

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

Se você deseja executar o próximo comando apenas se o comando anterior for bem-sucedido, use && para separar os comandos.

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

No seu caso, a execução de comandos consecutivos parece depender dos comandos anteriores; portanto, use o segundo exemplo, ou seja, use && para associar os comandos.

Prabhu
fonte
1
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install
Mark Stevens
fonte
não é o mesmo que o script OP, explique: se aa comando falhar, o script abort
Gilles Quenot
4
Além disso, você pode usar o cmd1 || cmd2separador se precisar cmd2executar apenas o cmd1status diferente de zero retornado ao shell e pode usar cmd1 ; cmd2se desejar executar os dois comandos, independentemente do status de retorno.
Victor Sorokin
@sputnick Deve-se, eu só colado-lo e concatenados os comandos com &&
Mark Stevens
3
@ MarkStevens É uma implementação melhor, mas não chegará aos mesmos resultados, como se os comandos fossem executados sequencialmente, acho que é isso que significa sputnick.
andrux
1

Qual é a utilidade de um único E comercial? Hoje de manhã, criei um iniciador no painel XFCE (no Manjaro + XFCE) para iniciar dois gerenciadores de senhas simultaneamente:

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

Mas não funciona como eu quero. IE, o primeiro aplicativo é iniciado, mas o segundo é iniciado apenas quando o anterior é fechado

No entanto, descobri que (com apenas um e comercial):

sh -c "keepassx & password-gorilla"

e funciona como eu quero agora ...

Nettlebay AP
fonte
1
O E comercial atua como um terminador de comando semelhante a ;, exceto que isso coloca o comman antes dele em segundo plano, ou seja, o shell não verá sua saída.
Sergiy Kolodyazhnyy
-1

Você pode usar como o seguinte código;

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

Funciona...

Deniz Güzel
fonte
-1

Acho muitas respostas para esse tipo de pergunta enganosa

Modificado a partir deste post: https://www.webmasterworld.com/linux/3613813.htm

O código a seguir criará a janela do bash e funciona exatamente como uma janela do bash. Espero que isto ajude. Muitas respostas erradas / que não funcionam por aí ...

            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
fonte