Que comando significa "não fazer nada" em um condicional no Bash?

180

Às vezes, ao fazer condicionais, preciso que o código não faça nada; por exemplo, aqui, quero que o Bash não faça nada quando $afor maior que "10", imprima "1" se $afor menor que "5", caso contrário, imprima "2":

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

Isso comete um erro. Existe um comando que não fará nada e também não diminua a velocidade do meu script?

Vila
fonte

Respostas:

340

O comando no-op no shell é :(dois pontos).

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

No manual do bash :

:(dois pontos)
Não faça nada além de expandir argumentos e executar redirecionamentos. O status de retorno é zero.

Barmar
fonte
3
@SaintHax Não, ele não roda true. Está embutido no shell e não faz nada.
Barmar 26/05
1
é shell embutido (você está correto), retorna true (status 0), assim como true, e é mais difícil de ler. Bash é uma linguagem do DevOps e, se :for escrita por alguém da minha equipe, eu pediria que eles mudassem.
SaintHax
3
@SaintHax Se alguém usou trueem um contexto não condicional, gostaria que eles mudassem. if trueestá bem, then trueparece errado.
Barmar 29/05
1
Claro, você pode simplesmente reescrever o código para usar em if ! condition; then do something; fivez de if condition; then :; else do something; fi.
Barmar
Eu concordo com você. Este exemplo pode ser escrito se / elif / else usando condições compostas e seria melhor.
SaintHax
38

Você provavelmente pode apenas usar o truecomando:

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

Uma alternativa, no seu caso de exemplo (mas não necessariamente em todos os lugares), é reordenar o seu if / else:

if [ "$a" -le 5 ]; then
    echo "1"
elif [ "$a" -lt 10 ]; then
    echo "2"
fi
Flimzy
fonte
8
Se você não testar o resultado, truee falsefor efetivamente não operacional no que diz respeito ao script, mas, em princípio, eles poderão criar algumas conchas que aceitem essa sintaxe, então talvez :seja melhor.
dmckee --- gatinho ex-moderador
3
A pergunta está marcada como bash. No bash truee falsesão embutidos. Para os reservatórios mais antigos, true, false, e até mesmo :pode ser comandos externos (embora você provavelmente veria esta última apenas no muito conchas de idade).
Keith Thompson
6
Eu prefiro :simplesmente porque é mais explícito que a intenção é
Freedom_Ben
9

Embora eu não esteja respondendo à pergunta original referente ao comando no-op, muitos (se não a maioria) dos problemas em que alguém pode pensar " neste ramo, não preciso fazer nada " podem ser contornados simplesmente reestruturando a lógica para que esse ramo ganhe. ocorrer.

Eu tento dar uma regra geral usando o exemplo de OPs

não faça nada quando $ a for maior que "10", imprima "1" se $ a for menor que "5", caso contrário, imprima "2"

temos que evitar um ramo em que $aobtenha mais de 10, para $a < 10que uma condição geral possa ser aplicada a todas as outras condições a seguir.

Em termos gerais, quando você diz não fazer nada quando X , então reformulá-la como evitar um ramo onde X . Normalmente, você pode fazer com que a evitação aconteça simplesmente negando o X e aplicando-o a todas as outras condições.

Portanto, o exemplo dos POs com a regra aplicada pode ser reestruturado da seguinte maneira:

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

Apenas uma variação do exposto, incluindo tudo na $a < 10condição:

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

(Para este exemplo específico, a reestruturação da @Flimzys é certamente melhor, mas eu queria dar uma regra geral para todas as pessoas que pesquisam como não fazer nada.)

KeyNone
fonte
5
Uma das razões pelas quais alguém pode querer não participar é quando estruturar o código inicialmente com a ideia de adicionar um "adicione algo aqui mais tarde" sem ter efeitos colaterais inadvertidos. Por exemplo, se alguém estiver colocando um if-then-else-fi em um .bashrc, se você colocar, echo "put stuff here"ele interromperá alguns dos usos que não são de logon (por exemplo, o scp é quebrado) e apenas espaço em branco / comentários causa um erro de tempo de execução.
Aphoid