Qual é a diferença entre : e verdadeiro?

Qual é a diferença entre : e verdadeiro?

Em bash:

$ type :
: is a shell builtin
$ type true
true is a shell builtin

Parece que são iguais, mas não fornecem o mesmo rastreamento do sistema:

$ strace :
strace: :: command not found
$ strace true
execve("/bin/true", ["true"], [/* 82 vars */]) = 0
[snip]
exit_group(0)                           = ?

Tentei diff strace bash -c : 2>:.txte strace bash -c true 2>true.txt, mas não consegui encontrar nenhuma diferença entre eles, exceto nos locais de memória.

Em dash:

$ type :
: is a special shell builtin
$ type true
true is a shell builtin

OK, então eles não são iguais. help :e help truenão são muito úteis e retornam o mesmo em bashand dash. Existe alguma diferença prática entre eles, exceto que :economiza três bytes e torna os scripts menos legíveis?

Responder1

Não há diferença real no comportamento. Ambos os comandos não fazem nada e saem com status de sucesso. :enfatiza não fazer nada; trueenfatiza o status de sucesso.

strace truefunciona porque trueé um comando interno do shell e um comando externo ( /bin/true); :é apenas um shell embutido (não existe /bin/:- embora pudesse existir, e provavelmente existia em sistemas Unix muito antigos). No bash, tente

type -a :
type -a true

As razões pelas quais ambos existem são históricas. Se bem me lembro, alguns shells muito antigos não tinham uma sintaxe de comentário, então o :comando do-nothing foi usado.

Há alguma diferença interna em dash. Olhando através da fonte, disponível em git://git.kernel.org/pub/scm/utils/dash/dash.git, mostra alguns caminhos de código diferentes em eval.c, mas não consegui produzir nenhum comportamento visivelmente diferente de outro do que a palavra specialna saída de type :.

Responder2

Eles são idênticos no Bash. Veja builtins/colon.defo código-fonte do Bash-4.2.

No seu comando, strace truevocê está realmente executando o binário /bin/trueem vez do true integrado do bash.

Responder3

A diferença entre os comandos é que por definição :é umespecial embutidoutilidade enquanto trueé umembutido regularutilitário em shells compatíveis com POSIX.

De acordo com a especificação POSIX,embutidos especiaissão tratados de forma ligeiramente diferente de uma forma que:

atribuições de variáveis ​​​​que precedem a invocação de um utilitário integrado especial permanecem em vigor após a conclusão do integrado; este não será o caso de um utilitário integrado regular ou outro utilitário.

Isso pode ser ilustrado em shells compatíveis com POSIX da seguinte forma:

$ VAR=FOO
$ VAR=BAR :
$ echo "$VAR"
BAR
$ VAR=FOO
$ VAR=BAR true
$ echo "$VAR"
FOO

Outro aspecto da diferença é que:

um erro em um utilitário interno especial pode fazer com que um shell que esteja executando esse utilitário seja abortado, enquanto um erro em um utilitário interno regular não deve fazer com que um shell que esteja executando esse utilitário seja abortado.

Código de exemplo em ação:

$ ( : > ""; echo "You won't see this!" )
sh: 1: cannot create : Directory nonexistent
$  echo "Exit code: $?"
Exit code: 2
$ ( true > ""; echo "Hello!" )
sh: 1: cannot create : Directory nonexistent
Hello!
$ echo "Exit code: $?"
Exit code: 0

informação relacionada