Was ist der Unterschied zwischen: und true?

Was ist der Unterschied zwischen: und true?

In bash:

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

Sieht aus, als wären sie gleich, aber sie geben nicht die gleiche Systemverfolgung aus:

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

Ich habe versucht, zwischen strace bash -c : 2>:.txtund zu unterscheiden strace bash -c true 2>true.txt, konnte aber außer den Speicherorten keine Unterschiede zwischen ihnen feststellen.

In dash:

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

OK, sie sind also nicht dasselbe. help :und sind nicht sehr nützlich und geben in und help truedasselbe zurück . Gibt es überhaupt einen praktischen Unterschied zwischen ihnen, außer dass drei Bytes gespart werden und Skripte weniger lesbar werden?bashdash:

Antwort1

Es gibt keinen wirklichen Unterschied im Verhalten. Beide Befehle tun nichts und werden mit einem erfolgreichen Status beendet. :betont, dass nichts getan wird; truebetont den erfolgreichen Status.

strace truefunktioniert, weil truesowohl ein Shell-Builtin als auch ein externer Befehl ( /bin/true) ist; :ist nur ein Shell-Builtin (es gibt kein /bin/:-- obwohl es eines geben könnte und auf sehr alten Unix-Systemen wahrscheinlich auch gab). Versuchen Sie in Bash

type -a :
type -a true

Die Gründe für die Existenz beider sind historischer Natur. Wenn ich mich recht erinnere, hatten einige sehr frühe Shells keine Kommentarsyntax, sodass :stattdessen der Befehl „Nichts tun“ verwendet wurde.

Es gibt einige interne Unterschiede in dash. Ein Blick in den Quellcode (verfügbar unter git://git.kernel.org/pub/scm/utils/dash/dash.git) zeigt einige unterschiedliche Codepfade in eval.c, aber ich konnte außer dem Wort specialin der Ausgabe von kein sichtbar unterschiedliches Verhalten erzielen type :.

Antwort2

In Bash sind sie identisch. Sehen Sie sich builtins/colon.defden Quellcode von Bash-4.2 an.

In Ihrem Befehl strace trueführen Sie tatsächlich die Binärdatei /bin/trueund nicht das in Bash integrierte „True“ aus.

Antwort3

Der Unterschied zwischen den Befehlen besteht darin, dass per Definition :einspezielle eingebauteDienstprogramm, während trueist einregulär eingebautDienstprogramm in POSIX-kompatiblen Shells.

Gemäß POSIX-Spezifikation,spezielle Einbautenwerden leicht unterschiedlich behandelt, und zwar auf folgende Weise:

Variablenzuweisungen vor dem Aufruf eines speziellen integrierten Dienstprogramms bleiben auch nach Abschluss des integrierten Dienstprogramms wirksam. Dies sollte bei regulären integrierten oder anderen Dienstprogrammen nicht der Fall sein.

Dies kann in POSIX-kompatiblen Shells wie folgt veranschaulicht werden:

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

Ein weiterer Unterschied besteht darin:

Ein Fehler in einem speziellen integrierten Dienstprogramm kann dazu führen, dass die Ausführung einer Shell dieses Dienstprogramms abgebrochen wird, während ein Fehler in einem regulären integrierten Dienstprogramm nicht dazu führen darf, dass die Ausführung einer Shell dieses Dienstprogramms abgebrochen wird.

Beispielcode in Aktion:

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

verwandte Informationen