¿Cuál es la diferencia entre : y verdadero?

¿Cuál es la diferencia entre : y verdadero?

En bash:

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

Parece que son iguales, pero no dan el mismo seguimiento del sistema:

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

Intenté diferenciar strace bash -c : 2>:.txty strace bash -c true 2>true.txt, pero no pude encontrar ninguna diferencia entre ellos, excepto las ubicaciones de la memoria.

En dash:

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

Bien, entonces no son lo mismo. help :y help trueno son muy útiles y devuelven lo mismo en bashy dash. ¿Existe alguna diferencia práctica entre ellos, excepto que :ahorra tres bytes y hace que los scripts sean menos legibles?

Respuesta1

No hay una diferencia real en el comportamiento. Ambos comandos no hacen nada y salen con un estado exitoso. :enfatiza no hacer nada; trueenfatiza el estado exitoso.

strace truefunciona porque truees tanto un comando interno del shell como un comando externo ( /bin/true); :es sólo un shell incorporado (no lo hay /bin/:, aunque podría haberlo, y probablemente lo había en sistemas Unix muy antiguos). En bash, prueba

type -a :
type -a true

Las razones por las que ambas existen son históricas. Si no recuerdo mal, algunos shells muy antiguos no tenían una sintaxis de comentarios, por lo que :en su lugar se utilizó el comando de no hacer nada.

Hay alguna diferencia interna en dash. Al revisar la fuente, disponible en git://git.kernel.org/pub/scm/utils/dash/dash.git, se muestran algunas rutas de código diferentes en eval.c, pero no he podido producir ningún comportamiento visiblemente diferente. que la palabra specialen la salida de type :.

Respuesta2

Son idénticos en Bash. Mire builtins/colon.defel código fuente de Bash-4.2.

En su comando, strace trueen realidad está ejecutando el binario /bin/trueen lugar del bash incorporado verdadero.

Respuesta3

La diferencia entre los comandos es que por definición :es unespecial incorporadoutilidad mientras que truees unaincorporado regularutilidad en shells compatibles con POSIX.

Según la especificación POSIX,incorporados especialesse tratan de manera ligeramente diferente de manera que:

las asignaciones de variables que preceden a la invocación de una utilidad incorporada especial permanecen vigentes una vez que se completa la utilidad incorporada; este no será el caso con una utilidad incorporada normal o de otro tipo.

Esto se puede ilustrar en shells compatibles con POSIX de la siguiente manera:

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

Otro aspecto de la diferencia es que:

un error en una utilidad incorporada especial puede provocar que se cancele el shell que ejecuta esa utilidad, mientras que un error en una utilidad incorporada normal no provocará que se cancele el shell que ejecuta esa utilidad.

Código de ejemplo en acción:

$ ( : > ""; 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

información relacionada