449 Stimmen

Was ist der Zweck des : (Doppelpunkt) GNU Bash builtin?

Was ist der Zweck eines Befehls, der nichts tut und kaum mehr als ein Vorspann für einen Kommentar ist, der aber selbst ein Shell-Builtin ist?

Es ist um etwa 40% pro Aufruf langsamer als das Einfügen eines Kommentars in Ihre Skripte, was wahrscheinlich stark von der Größe des Kommentars abhängt. Die einzigen möglichen Gründe, die ich dafür sehen kann, sind die folgenden:

# poor man's delay function
for ((x=0;x<100000;++x)) ; do : ; done

# inserting comments into string of commands
command ; command ; : we need a comment in here for some reason ; command

# an alias for `true'
while : ; do command ; done

Ich schätze, was ich wirklich suche, ist, welche historische Anwendung es gehabt haben könnte.

527voto

earl Punkte 37791

Historisch hatten die Bourne-Shells keine true y false als integrierte Befehle. true wurde stattdessen einfach als Aliasing auf : y false zu etwas wie let 0 .

: ist etwas besser als true für die Übertragbarkeit auf alte, von Bourne abgeleitete Shells. Ein einfaches Beispiel ist die Tatsache, dass weder die ! Pipelinebetreiber noch die || Listenoperator (wie es bei einigen alten Bourne-Shells der Fall war). Damit bleibt der else Klausel des if Anweisung als einziges Mittel zur Verzweigung aufgrund des Exit-Status:

if command; then :; else ...; fi

Desde if erfordert eine nicht leere then Klausel und Kommentare gelten nicht als nicht-leer, : dient als No-op.

Heutzutage (d.h. in einem modernen Kontext) können Sie normalerweise entweder : o true . Beide sind durch POSIX spezifiziert, und einige finden true leichter zu lesen. Allerdings gibt es einen interessanten Unterschied: : ist eine sogenannte POSIX speziell eingebaut in der Erwägung, dass true est un regulär eingebaut .

  • Spezielle Built-Ins müssen in die Shell eingebaut werden; reguläre Built-Ins werden nur "normalerweise" eingebaut, aber das ist nicht unbedingt garantiert. Normalerweise sollte es kein reguläres Programm namens : mit der Funktion von true im PATH der meisten Systeme.

  • Der wahrscheinlich wichtigste Unterschied ist, dass bei speziellen Built-Ins jede Variable, die durch das Built-In gesetzt wird - auch in der Umgebung während der einfachen Befehlsauswertung - nach Beendigung des Befehls bestehen bleibt, wie hier anhand von ksh93 demonstriert:

    $ unset x; ( x=hi :; echo "$x" )
    hi
    $ ( x=hi true; echo "$x" )
    
    $

    Beachten Sie, dass Zsh diese Anforderung ignoriert, ebenso wie GNU Bash, außer wenn sie im POSIX-Kompatibilitätsmodus arbeitet, aber alle anderen großen "von POSIX sh abgeleiteten" Shells beachten dies, einschließlich dash, ksh93 und mksh.

  • Ein weiterer Unterschied besteht darin, dass reguläre Built-Ins kompatibel sein müssen mit exec - hier mit der Bash demonstriert:

    $ ( exec : )
    -bash: exec: :: not found
    $ ( exec true )
    $
  • POSIX weist auch ausdrücklich darauf hin, dass : kann schneller sein als true obwohl dies natürlich ein implementierungsspezifisches Detail ist.

93voto

Kevin Little Punkte 11796

Ich benutze es, um variable Befehle einfach zu aktivieren/deaktivieren:

#!/bin/bash
if [[ "$VERBOSE" == "" || "$VERBOSE" == "0" ]]; then
    vecho=":"     # no "verbose echo"
else
    vecho=echo    # enable "verbose echo"
fi

$vecho "Verbose echo is ON"

So

$ ./vecho
$ VERBOSE=1 ./vecho
Verbose echo is ON

Das sorgt für ein sauberes Skript. Dies kann nicht mit '#' gemacht werden.

Auch,

: >afile

ist eine der einfachsten Möglichkeiten, um zu garantieren, dass 'afile' existiert, aber 0 Länge hat.

88voto

ormaaj Punkte 5809

Eine nützliche Anwendung für : ist, wenn Sie nur daran interessiert sind, Parametererweiterungen für ihre Nebeneffekte zu verwenden, anstatt ihr Ergebnis tatsächlich an einen Befehl zu übergeben.

In diesem Fall verwenden Sie die Parametererweiterung als Argument für entweder : o false je nachdem, ob Sie einen Exit-Status von 0 oder 1 wünschen. Ein Beispiel könnte sein

: "${var:=$1}"

Desde : ein eingebautes Programm ist, sollte es ziemlich schnell sein.

64voto

zagpoint Punkte 629

: kann auch für Blockkommentare verwendet werden (ähnlich wie /* */ in der Sprache C). Wenn Sie zum Beispiel einen Codeblock in Ihrem Skript überspringen wollen, können Sie dies tun:

: << 'SKIP'

your code block here

SKIP

42voto

Flimm Punkte 112964

Zwei weitere Verwendungszwecke, die in anderen Antworten nicht erwähnt wurden:

Protokollierung

Nehmen Sie dieses Beispielskript:

set -x
: Logging message here
example_command

Die erste Zeile, set -x bewirkt, dass die Shell den Befehl ausgibt, bevor sie ihn ausführt. Das ist ein recht nützliches Konstrukt. Der Nachteil ist, dass die übliche echo Log message Anweisung wird die Nachricht nun zweimal gedruckt. Die Doppelpunkt-Methode umgeht dies. Beachten Sie, dass Sie immer noch Sonderzeichen auslassen müssen, genau wie bei echo .

Cron-Job-Titel

Ich habe gesehen, dass es in Cron-Jobs verwendet wird, wie hier:

45 10 * * * : Backup for database ; /opt/backup.sh

Dies ist ein Cron-Job, der das Skript ausführt /opt/backup.sh jeden Tag um 10:45 Uhr. Der Vorteil dieser Technik ist, dass die E-Mail-Betreffs besser aussehen, wenn die /opt/backup.sh gibt eine Ausgabe aus.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X