Ejecute dos comandos en caso de || o &&

10

He leído sobre && y || y me gustaría ejecutar dos comandos en el caso falso.

Lo he intentado ;pero eso siempre funciona . He intentado ponerlo entre llaves { command1; command2 }pero eso produce un error de sintaxis.

Quiero hacer algo como

command && echo "Ok, continuing" || echo "Check internet connection"; exit 1

que solo sale si no hay conexión a Internet.

Thomas Weller
fuente
1
Esto parece un simple error tipográfico. Una pregunta mucho más interesante es las diferencias entre ()y {}.
edwinksl

Respuestas:

26

El uso de parens coloca los comandos en una subshell que no siempre es lo que desea. Alternativamente, use llaves:

command && echo "Ok, continuing" || { echo "Check internet connection"; exit 1; }

El truco aquí es que, a diferencia de los parens, el comando final entre llaves debe ser seguido por ;.

Por qué se requiere un punto y coma o una nueva línea

Una llave rizada es un argumento válido para un comando. Por ejemplo, aquí hay una llave rizada como argumento para echo:

$ echo }
}

En consecuencia, si el shell ve:

{ command1; command2 }

El shell interpreta que command1 no tiene argumentos y command2 tiene un argumento que consiste en el carácter }. Una llave rizada }solo se interpreta como cierre de una agrupación si sigue un punto y coma o una nueva línea. Para hacer que lo anterior funcione:

{ command1; command2; }

Subcapas y la diferencia entre {...}y(...)

Observe que lo siguiente se establece xen 10 pero que esa configuración se olvida antes de que se echoejecute el comando:

$ x=0; false || ( echo Hello; x=10 )
Hello
$ echo $x
0

Con llaves, por el contrario, x=10se recuerda la configuración de :

$ x=0; false || { echo Hello; x=10; }
Hello
$ echo $x
10

La diferencia se debe a que las asignaciones variables en una subshell no sobreviven una vez que se completa la subshell.

Documentación

De man bash:

(lista)

La lista se ejecuta en un entorno de subshell (ver ENTORNO DE EJECUCIÓN DE MANDOS a continuación). Las asignaciones variables y los comandos incorporados que afectan el entorno del shell no permanecen vigentes una vez que se completa el comando. El estado de retorno es el estado de salida de la lista.

{lista; }

La lista simplemente se ejecuta en el entorno de shell actual. La lista debe terminarse con una nueva línea o punto y coma. Esto se conoce como un comando de grupo. El estado de retorno es el estado de salida de la lista. Tenga en cuenta que, a diferencia de los metacaracteres (y), {y} son palabras reservadas y deben aparecer donde se permite reconocer una palabra reservada. Como no causan un salto de palabra, deben estar separados de la lista por espacios en blanco u otro metacarácter de shell.

[Énfasis añadido]

John1024
fuente