Lo cual es más idiomático en un script bash: `|| verdadero` o `|| : `?

36

No hago mucho script de shell, así que me sorprendí un poco cuando leí la documentacióngit submodule y vi la sintaxis que usaban en esta documentación:

Un retorno distinto de cero del comando en cualquier submódulo hace que el procesamiento finalice. Esto se puede anular agregando || :al final del comando.

Tuve que buscar que || :era una abreviatura para obligar a un comando a salir con éxito. Cada vez que tuve que hacer que un comando salga con éxito, solía || true. ¿Se || :considera más idiomático?

Mark Rushakoff
fuente
Vale la pena señalar que ||:(sin espacio) también es válido en bash. Hace lo mismo que || :o || true.
Bruno Bronosky

Respuestas:

38

trueno fue integrado en el shell Bourne. :siempre lo fue (era la forma de ingresar comentarios antes de que #se introdujera).

Eso, y porque es más corto que el tipo es probablemente la razón principal de la gente prefiere :más true.

Tenga en cuenta otra diferencia en los shells POSIX (para bash, solo en el modo POSIX): si bien truees un builtin normal (ni siquiera tiene que ser builtin), :es un builtin especial . Eso tiene algunas implicaciones, la mayoría de las cuales es poco probable que tengan algún impacto en este caso particular:

  • Si un :comando falla, incluso debido a una redirección fallida, eso hace que el shell salga. En la práctica, eso probablemente no hará la diferencia a menos que pase redirecciones a:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
  • en var=value :, varpermanece establecido valuedespués de :devoluciones, no en el caso de true:

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1

También tenga en cuenta que los || truetrabajos en los depósitos de la rcy cshlas familias, pero no || :(pero no cancelar set -een csh).

|| :No es lo mismo que :. Significa o se ejecuta de :otra manera (es decir, si falla la canalización anterior).

set -e
false

Causaría la cáscara para salir a causa de set -ey falsetiene un estado de salida no cero (fallo). El set -eefecto se cancela si el comando que devuelve un estado de salida distinto de cero se usa como una condición como en:

if false; then ...
while false; do ...
false && : ...
false || : ...

false && :Solo cancela set -e. false || :cancela set -ey establece el estado de salida de 0modo que es más idiomático decir que queremos ignorar un código de salida de falla del comando. La mayoría argumentaría que || truees más legible (transmite la intención más claramente).

Stéphane Chazelas
fuente
55
&& :es brillante, ¿hay documentos o lecturas adicionales sobre esto? Google se queda corto cuando intento encontrar este tipo de palabras clave ...
Ian Bytchek
5

En general, en bash, el colon :y truees equivalente.

Es || : considerado como más idiomático?

Creo que se basa en el contexto .

Si desea que a return value, o a conditionsea ​​siempre cierto, debe usar una truepalabra clave, hará que su código sea más claro y les permitirá a los espectadores saber que desea enfatizar el valor verdadero , es decir:

while true; do something

o

<commnad>
RETURN_VALUE= $? || true

Y si no quieres hacer nada , o NOPen shell, debes usar dos puntos:

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 

o

while conditon
do
    : # DO NOTHING HERE
done
Cuonglm
fuente
5

La mayoría de estas respuestas no abordan el uso más común de :.

Primero, esta discusión no está relacionada con ningún shell que no sea un derivado de Bourne shell ( sh). Dicho esto, todos los shells derivados de Bourne ven truey :como la misma cosa. Se solía animar a los programadores a usarlos en :lugar de hacerlo true, porque :siempre está integrado, mientras que solía haber casos en los que trueno siempre estaba integrado.

:Tiene dos usos. No es sinónimo de #, pero tiene una función diferente. Al depurar su script bajo a set -x, #el analizador descarta las líneas donde se usa y las ignora totalmente, mientras que las líneas con :se analizan y evalúan. Esto es realmente útil en la depuración ya que debajo de -xesas líneas se muestran y se muestra su valor después de la evaluación. Es como poner printdeclaraciones en su código que solo se muestran en -xmodo. Tenga cuidado con los valores después de :que son código real y los efectos secundarios pueden afectar su programa.

cdr
fuente
1
¿Cuál es el segundo uso?
Peter Mortensen