Ejecutar combinar múltiples comandos de Linux en una línea

329

Estoy tratando de fusionar múltiples comandos de Linux en una línea para realizar la operación de implementación. Por ejemplo

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

Respuestas:

717

Si desea ejecutar cada comando solo si el anterior tuvo éxito, combínelos con el &&operador:

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

Si falla uno de los comandos, no se ejecutarán todos los demás comandos que lo siguen.

Si desea ejecutar todos los comandos independientemente de si los anteriores fallaron o no, sepárelos con punto y coma:

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

En su caso, creo que desea el primer caso en el que la ejecución del siguiente comando depende del éxito del anterior.

También puede poner todos los comandos en un script y ejecutar eso en su lugar:

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

(Las barras invertidas al final de la línea están allí para evitar que el shell piense que la siguiente línea es un comando nuevo; si omite las barras invertidas, necesitaría escribir el comando completo en una sola línea).

Guarde eso en un archivo, por ejemplo myscript, y hágalo ejecutable:

chmod +x myscript

Ahora puede ejecutar ese script como otros programas en la máquina. Pero si no lo coloca dentro de un directorio listado en su PATHvariable de entorno (por ejemplo /usr/local/bin, o en algunas distribuciones de Linux ~/bin), entonces deberá especificar la ruta a ese script. Si está en el directorio actual, lo ejecuta con:

./myscript

Los comandos en el script funcionan de la misma manera que los comandos en el primer ejemplo; el siguiente comando solo se ejecuta si el anterior tuvo éxito. Para la ejecución incondicional de todos los comandos, simplemente enumere cada comando en su propia línea:

#! /bin/sh
cd /my_folder
rm *.jar
svn co path to repo
mvn compile package install
Nikos C.
fuente
38
Para futuros lectores: también puede usar en ||lugar de punto y coma o &&si solo desea que se ejecute el siguiente comando si falla el último. Como en probar esto, y si falla, intente eso.
DeVadder
3
Hm, los puntos y comas no siempre funcionan. Por ejemplo, ls >/dev/null & ; echo $!desencadena un error.
Hola Ángel, el
1
Y qué tail -f my.log & && ./myscriptpasa si quiero ejecutar el primer comando en segundo plano y otro en primer plano ... Estoy intentando esto que no funciona ... sugiérelo.
OverrockSTAR
44
@Pareshkumar Con bash, puede hacer: { tail -f my.log & } && ./myscriptSin embargo, tenga en cuenta que &&aquí no sirve de nada, ya que el primer trabajo se ejecuta en segundo plano y, por lo tanto, el segundo trabajo no puede conocer el resultado, ya que ambos trabajos comenzarán al mismo tiempo. Así que también podrías escribir:{ tail -f my.log & }; ./myscript
Nikos C.
¿Qué sucede si necesito sudopermisos para ejecutar uno de los comandos? ¿Debo poner el sudoprincipio de todos los comandos o solo el que lo necesita? ¿Cómo puedo pasar la contraseña a ese comando para que se ejecute correctamente?
Drubio
46

Lo he encontrado usando; separar comandos solo funciona en primer plano. p.ej :

cmd1; cmd2; cmd3 & - solo se ejecutará cmd3en segundo plano, mientras que cmd1 && cmd2 && cmd3 &- ejecutará toda la cadena en segundo plano SI no hay errores.

Para atender la ejecución incondicional, el uso de paréntesis resuelve esto:

(cmd1; cmd2; cmd3) & - ejecutará la cadena de comandos en segundo plano, incluso si falla algún paso.

Decano
fuente
1
¿Fue el ampersand final (&) en sus ejemplos intencional? Si es así, ¿para qué sirve?
Technophile
55
@Technophile Es ejecutar un comando en segundo plano
Oak Chantosa
1
Una respuesta simple, corta y directa, debe usar los sitios web de StackExchange con más frecuencia Dean. Gracias por tu contribución.
CPHPython
10

Puedes separar tus comandos usando un punto y coma:

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

¿A eso te referías?

andrux
fuente
3

Para ejecutarlos todos a la vez, puede usar la tecla de línea de tubería "|" al igual que:

$ cd /my_folder | rm *.jar | svn co path to repo | mvn compile package install
Kelly Poore
fuente
1
La canalización se está utilizando para dar la salida de su comando al siguiente comando como entrada. Por ejemplo: X | La salida del comando Y -> X funcionará como entrada para el comando Y
Arpan Saini
2

Si desea ejecutar todos los comandos, ya sea que se ejecute el anterior o no, puede usar punto y coma (;) para separar los comandos.

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

Si desea ejecutar el siguiente comando solo si el comando anterior tiene éxito, puede usar && para separar los comandos.

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

En su caso, la ejecución de comandos consecutivos parece depender de los comandos anteriores, así que use el segundo ejemplo, es decir, use && para unir los comandos.

Prabhu
fuente
1
cd /my_folder && rm *.jar && svn co path to repo && mvn compile package install
Mark Stevens
fuente
no es lo mismo que la secuencia de comandos OP, explique: si un comando falla, la secuencia de comandos aborta
Gilles Quenot
44
Además, puede usar el cmd1 || cmd2separador si necesita cmd2ejecutar solo si se cmd1devuelve el estado distinto de cero al shell, y puede usarlo cmd1 ; cmd2si desea ejecutar ambos comandos independientemente de su estado de retorno.
Victor Sorokin
@sputnick Debería ser, lo acabo de pegar y concatene los comandos con &&
Mark Stevens
3
@ MarkStevens Es una mejor implementación, pero no obtendrá los mismos resultados que si los comandos se ejecutaran secuencialmente, creo que eso es lo que significaba sputnick.
andrux
1

¿Cuál es la utilidad de un único Ampersand? Esta mañana, hice un lanzador en el panel XFCE (en Manjaro + XFCE) para lanzar 2 contraseñas a la vez:

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

Pero no funciona como yo quiero. Es decir, la primera aplicación se inicia pero la segunda solo comienza cuando la anterior está cerrada

Sin embargo, encontré que (con solo un ampersand):

sh -c "keepassx & password-gorilla"

y funciona como quiero ahora ...

Nettlebay AP
fuente
1
Ampersand actúa como un terminador de comando similar a ;, excepto que esto pone al comando delante de él en segundo plano, es decir, shell no verá su salida.
Sergiy Kolodyazhnyy
-1

Puedes usarlo como el siguiente código;

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

Funciona...

Deniz Güzel
fuente
-1

Encuentro muchas respuestas para este tipo de preguntas engañosas

Modificado de esta publicación: https://www.webmasterworld.com/linux/3613813.htm

El siguiente código creará una ventana bash y funciona exactamente como una ventana bash. Espero que esto ayude. Demasiadas respuestas incorrectas / que no funcionan ...

            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
fuente