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
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 comovalue
após:
retorna, não no caso detrue
:$ 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
||:
(sem espaço) também é válido no bash. Ele faz a mesma coisa que|| :
ou|| true
.