¿Qué comando significa "no hacer nada" en un condicional en Bash?

180

A veces, cuando hago condicionales, necesito que el código no haga nada, por ejemplo, aquí, quiero que Bash no haga nada cuando $asea ​​mayor que "10", imprima "1" si $aes menor que "5", de lo contrario, imprima "2":

if [ "$a" -ge 10 ]
then
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

Sin embargo, esto hace un error. ¿Hay un comando que no haga nada y que tampoco ralentice mi script?

Pueblo
fuente

Respuestas:

340

El comando no-op en shell es :(dos puntos).

if [ "$a" -ge 10 ]
then
    :
elif [ "$a" -le 5 ]
then
    echo "1"
else
    echo "2"
fi

Del manual de bash :

:(dos puntos)
No haga nada más que expandir argumentos y realizar redirecciones. El estado de retorno es cero.

Barmar
fuente
3
@SaintHax No, no se ejecuta true. Está integrado en el caparazón y no hace nada.
Barmar
1
está integrado en el shell (estás en lo correcto), devuelve verdadero (estado 0) al igual que verdadero, y es más difícil de leer. Bash es un lenguaje DevOps, y si :alguien lo escribe en mi equipo, les pediría que lo cambien.
SaintHax
3
@SaintHax Si alguien usara trueen un contexto no condicional, les pediría que lo cambien. if trueEstá bien, then trueparece mal.
Barmar
1
Por supuesto, simplemente puede reescribir el código para usar en if ! condition; then do something; filugar de if condition; then :; else do something; fi.
Barmar
Estoy de acuerdo contigo. Este ejemplo podría escribirse si / elif / else usa condiciones compuestas y sería mejor.
SaintHax
38

Probablemente puedas usar el truecomando:

if [ "$a" -ge 10 ]; then
    true
elif [ "$a" -le 5 ]; then
    echo "1"
else
    echo "2"
fi

Una alternativa, en su caso de ejemplo (pero no necesariamente en todas partes) es reordenar su if / else:

if [ "$a" -le 5 ]; then
    echo "1"
elif [ "$a" -lt 10 ]; then
    echo "2"
fi
Flimzy
fuente
8
Si no prueba el resultado tanto truey falseefectivamente no hay operaciones en lo que respecta al script, pero en principio podrían bifurcar algunos shells que aceptan esta sintaxis, por lo que tal vez :sea ​​mejor.
dmckee --- ex gatito moderador
3
La pregunta está etiquetada bash. En bash, truey falseson incorporados. Para los depósitos de más edad, true, false, e incluso :podría ser comandos externos (aunque probablemente vería este último sólo en muy antiguas conchas).
Keith Thompson
66
Prefiero :simplemente porque es más explícito cuál es la intención
Freedom_Ben
9

Aunque no estoy respondiendo a la pregunta original sobre el comando no-op, muchos (si no la mayoría) de los problemas cuando uno puede pensar " en esta rama no tengo que hacer nada " pueden evitarse simplemente reestructurando la lógica para que esta rama gane No ocurra.

Intento dar una regla general usando el ejemplo de OP

no haga nada cuando $ a sea mayor que "10", imprima "1" si $ a es menor que "5", de lo contrario, imprima "2"

tenemos que evitar una rama donde $aobtiene más de 10, por lo $a < 10que una condición general se puede aplicar a todos los demás, después de la condición.

En términos generales, cuando se dice no hacer nada cuando X , entonces reformular como evitar una sucursal en la que X . Por lo general, puede evitarlo simplemente negando X y aplicándolo a todas las demás condiciones.

Por lo tanto, el ejemplo de OP con la regla aplicada puede reestructurarse como:

if [ "$a" -lt 10 ] && [ "$a" -le 5 ]
then
    echo "1"
elif [ "$a" -lt 10 ]
then
    echo "2"
fi

Solo una variación de lo anterior, que incluye todo en la $a < 10condición:

if [ "$a" -lt 10 ]
then
    if [ "$a" -le 5 ]
    then
        echo "1"
    else
        echo "2"
    fi
fi

(Para este ejemplo específico, la reestructuración de @Flimzys es ciertamente mejor, pero quería dar una regla general para todas las personas que buscan cómo no hacer nada).

KeyNone
fuente
55
Una razón por la que alguien podría querer tener un no-op es cuando inicialmente se estructura el código con la idea de que se agregará el "agregar algo aquí más tarde" sin tener efectos secundarios involuntarios. Por ejemplo, si uno coloca un if-then-else-fi en un .bashrc, si lo coloca echo "put stuff here"interrumpirá algunos de los usos que no son de inicio de sesión (por ejemplo, scp se rompe), y solo los espacios en blanco / comentarios causan un error de tiempo de ejecución.
Aphoid