Eu hackeei muitos scripts shell e, às vezes, as coisas mais simples me confundem. Hoje, deparei-me com um script que fazia uso extensivo do :
bash (dois pontos) incorporado.
A documenação parece bastante simples:
: (a colon) : [arguments]
Não faça nada além de expandir argumentos e executar redirecionamentos. O status de retorno é zero.
No entanto, eu já vi isso apenas em demonstrações de expansão de shell. O caso de uso no script que eu deparei fez uso extensivo dessa estrutura:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
Na verdade, havia centenas de greps, mas são apenas mais do mesmo. Nenhum redirecionamento de entrada / saída está presente além da estrutura simples acima. Nenhum valor de retorno é verificado posteriormente no script.
Estou lendo isso como uma construção inútil que diz "ou não faça nada". Qual o propósito de terminar com esses "cumprimentos" ou "não fazer nada"? Em que caso essa construção causaria um resultado diferente do que simplesmente deixar de fora || :
todas as instâncias?
fonte
:
como alternativatrue
. Talvezerrexit
esteja definido e o autor não se importe com o status de saída de alguns comandos.Respostas:
Parece que os
:
s no seu script estão sendo usados no lugartrue
. Segrep
não encontrar uma correspondência no arquivo, ele retornará um código de saída diferente de zero; como jw013 menciona em um comentário, seerrexit
estiver definido, provavelmente-e
na linha shebang, o script sairá se algum dosgrep
s falhar em encontrar uma correspondência. Claramente, não era isso que o autor queria, então ele adicionou|| :
para tornar o status de saída desse comando composto sempre zero, como o mais comum (na minha experiência)|| true
/|| /bin/true
.fonte
true
, mas a intenção semântica é muito mais claratrue
.:
é mais adequado quando um NOP explícito é desejado.:
vez de,true
porque:
é umbash
built-in, ondetrue
normalmente é um binário compilado com mais sobrecarga. Normalmente eu usotrue
porque o código é mais legível (da mesma forma eu prefiro usar emsource
vez de.
).O
:
built-in também é útil com a expansão do shell "atribuir valores padrão" do Bash, onde a expansão é frequentemente usada apenas para o efeito colateral e o valor expandido é descartado:fonte
Posso pensar em dois lugares que usei
:
no passado.Esse é um ciclo para sempre.
Coloque uma função de esboço, apenas para corrigir o fluxo de controle de nível superior.
Um uso que eu já vi nos velhos tempos: em vez de uma
#!/bin/sh
(ou qualquer outra) linha, você veria uma:
linha. Alguns dos kernels do Real Unix mais antigos ou shells do Real Unix usariam isso para significar "eu sou um script de shell, eles devem me executar". Pelo que me lembro, foi exatamente quando o csh estava fazendo incursões como um shell interativo comum.fonte
:
é muito estranho. Eu descobri que ele realmente faz com que o script seja executadosh
. onde, como quando você inicia o script sem um shebang ... ele tenta executar o script com qualquer shell que esteja sendo executado (por isso, se você estiver executando,bash
ele tentará executá-lo comobash
se tivesse, emcsh
seguida, ele tentará executá-lo comocsh
).O
:
built-in já estava no shell Thompson - foi documentado para o Unix V6 em 1975. No shell Thompson,:
indicou um rótulo para ogoto
comando. Se você nunca tentou chamargoto
uma linha iniciada por:
, essa linha era efetivamente um comentário.O shell Bourne , o ancestral dos shells Bourne / POSIX como os conhecemos, nunca teve um
goto
que eu saiba, mas foi mantido:
como um comando não operacional (já estava presente no Unix V7 ).fonte
Eu descobri uma referência antiga: "O ambiente de programação UNIX" (c) 1984 por Kernighan e Pike.
A página 147 (Programação de shell) diz o seguinte:
fonte
true
agora também é um shell embutido em muitos sistemas.Parece que me lembro que as versões anteriores do shell não tinham uma sintaxe de comentário. Uma linha iniciada com
:
(que provavelmente teria sido um executável real, semelhante a/bin/true
) teria sido a melhor alternativa.Aqui está uma página de manual para o antigo shell Thompson (sem relação); não há menção a nenhuma sintaxe de comentário.
fonte
:
era de fato um indicador de etiqueta para ogoto
comando, em alguma casca antiga (não sei qual). Um rótulo: something
poderia realmente ser usado como um comentário, se não houvesse correspondênciagoto
. A prática continuou mesmo depois de tergoto
desaparecido.":" é útil para depuração.
Executando normalmente, a função de depuração nunca é executada, portanto, basta passar por cima do noop (variáveis e curingas são expandidos). Se for necessária uma depuração mais aprofundada, remova o noop da variável e a função de depuração será chamada com os argumentos necessários.
Outro uso útil é como um comentário em bloco, que é um recurso ausente da sintaxe do shell.
fonte