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>:.txt
und 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 true
dasselbe zurück . Gibt es überhaupt einen praktischen Unterschied zwischen ihnen, außer dass drei Bytes gespart werden und Skripte weniger lesbar werden?bash
dash
:
Antwort1
Es gibt keinen wirklichen Unterschied im Verhalten. Beide Befehle tun nichts und werden mit einem erfolgreichen Status beendet. :
betont, dass nichts getan wird; true
betont den erfolgreichen Status.
strace true
funktioniert, weil true
sowohl 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 special
in der Ausgabe von kein sichtbar unterschiedliches Verhalten erzielen type :
.
Antwort2
In Bash sind sie identisch. Sehen Sie sich builtins/colon.def
den Quellcode von Bash-4.2 an.
In Ihrem Befehl strace true
führen Sie tatsächlich die Binärdatei /bin/true
und nicht das in Bash integrierte „True“ aus.
Antwort3
Der Unterschied zwischen den Befehlen besteht darin, dass per Definition :
einspezielle eingebauteDienstprogramm, während true
ist 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