O que é mais idiomático em um script bash: `|| true` ou `|| : `?

Não faço muito shell scripting, então fiquei um pouco surpreso quando li a documentação de git submodule e vi a sintaxe que eles usaram nesta documentação:

A o retorno diferente de zero do comando em qualquer submódulo faz com que o processamento seja encerrado. Isso pode ser anulado adicionando || : ao final do comando.

Tive que verificar que || : era uma forma abreviada de forçar a saída de um comando com sucesso. Sempre que tive que fazer uma saída de comando com sucesso , Usei || true. é considerado mais idiomático?

Comentários

  • É ' É importante notar que ||: (sem espaço) também é válido no bash. Ele faz a mesma coisa que || : ou || true.

Resposta

true não foi integrado ao Bourne shell. : sempre foi (era a maneira de inserir comentários antes de # ser introduzido).

Isso, e porque é mais curto digitar é provavelmente a principal razão pela qual as pessoas preferem : a true.

Observe outra diferença em Shells POSIX (para bash, apenas no modo POSIX): enquanto true é um integrado regular (nem mesmo precisa ser integrado) , : é um especial integrado. Isso tem algumas implicações, a maioria das quais é improvável que tenha qualquer impacto neste caso específico:

  • Se um comando : falhar, inclusive devido a um redirecionamento com falha, que faz com que o shell seja encerrado. Na prática, isso provavelmente não fará diferença a menos que você passe redirecionamentos para :

    $ sh -c ": > / ; echo HERE" sh: 1: cannot create /: Is a directory $ sh -c "true > /; echo HERE" sh: 1: cannot create /: Is a directory HERE 
  • em var=value :, var permanece definido como value após : retorna, não no caso de true:

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

Observe também que || true funciona em shells de rc e csh famílias, mas não || : (mas não para cancelar set -e em csh).

|| : não é o mesmo que :. Significa ou execute : caso contrário (isto é, se o pipeline anterior falhar).

set -e false 

Faria com que o shell fosse encerrado devido a set -e (também conhecido como a opção errexit) e tem um status de saída diferente de zero (falha). O set -e efeito é cancelado se o comando que retorna um status de saída diferente de zero for usado como uma condição como em:

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

false && : cancela apenas set -e. false || : cancela o efeito de set -e e define o status de saída para 0, portanto é mais idiomático para dizer que queremos ignorar um código de saída de falha do comando. A maioria argumentaria que || true é mais legível (transmite a intenção com mais clareza).

Comentários

  • && : é brilhante, há algum documento ou leitura adicional sobre isso? O Google não consegue encontrar este tipo de palavras-chave…

Resposta

A maioria dessas respostas não consegue abordar o uso mais comum de :.

Primeiro, esta discussão não está relacionada a qualquer shell que não seja um Bourne shell (sh) derivado. Dito isso, todos os shells derivados de Bourne veem true e : como a mesma coisa. Os programadores eram incentivados a usar : em vez de true, porque : é sempre um integrado, embora houvesse casos em que true nem sempre era integrado.

: tem dois usos. Não é sinônimo de #, mas tem uma função diferente. Ao depurar seu script em um set -x, as linhas onde # é usado são descartadas pelo analisador e totalmente ignoradas, enquanto as linhas com : são analisados e avaliados. Isso é realmente útil na depuração, pois em -x essas linhas são mostradas e seus valores após a avaliação são exibidos.É como colocar print instruções em seu código que só aparecem no modo -x. Tenha cuidado com os valores após :, pois eles são códigos reais e os efeitos colaterais podem afetar seu programa.

Comentários

  • Qual é o segundo uso?

Resposta

Geralmente, no bash, o dois pontos : e true são equivalentes.

É | | : considerado mais idiomático?

Acho que é baseado no contexto .

Se você quiser um return value ou condition é sempre verdadeiro , você deve usar true palavra-chave, isso tornará seu código mais claro e permitirá que os visualizadores saibam que você deseja enfatizar o valor true , ou seja:

while true; do something 

ou

<commnad> RETURN_VALUE= $? || true 

E se você quiser não fazer nada ou NOP no shell, você deve usar dois pontos :

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

ou

while conditon do : # DO NOTHING HERE done 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *