Was bedeutet ein Bindestrich "-" am Ende eines Befehls?

78

Mit folgendem Befehl:

gzip -dc /cdrom/cdrom0/file.tar.gz | tar xvf 

Was bedeutet das -am Ende des Befehls? Ist es eine Art Platzhalter?

Eugene S
quelle
3
Ein kleines Detail zu erwähnen: Das -muss nicht am Ende des Befehls stehen. Zum Beispiel: ls -l | diff - /old_ls_output.txt.
Manatwork

Antworten:

82

In diesem Fall bedeutet es "Standardeingabe". Es wird von einigen Programmen (zB tar) verwendet, wenn ein Dateiargument erforderlich ist und Sie stattdessen stdin verwenden müssen. Es ist kein Shell-Konstrukt und es hängt von dem Programm ab, das Sie verwenden. Überprüfen Sie im Zweifelsfall die Manpage!

In diesem Fall ist die Standardeingabe das Argument für die -fOption. In Fällen, in denen dies -nicht unterstützt wird, können Sie mit so etwas wie tar xvf /proc/self/fd/0oder davonkommen tar xvf /dev/stdin(letzteres wird von verschiedenen Unices weitgehend unterstützt).

Verlassen Sie sich nicht darauf, dass dies allgemein „Standardeingabe“ bedeutet. Da es von der Shell nicht interpretiert wird, kann jedes Programm frei damit umgehen. In einigen Fällen ist es Standard - Ausgabe oder etwas ganz anderes: auf sumich bedeutet ‚ein Login - Shell starten‘. In anderen Fällen wird es überhaupt nicht interpretiert. Das Muskelgedächtnis hat mich dazu gebracht, einige Dateien mit dem Namen zu erstellen, -weil eine Version eines Programms, mit dem ich gearbeitet habe, den Gedankenstrich nicht verstand.

Alexios
quelle
4
Es kann auch bedeuten STDOUT, je nach Kontext.
Bahamat
3
Und so ziemlich alles andere, da es an den einzelnen Programmen liegt, diese zu interpretieren.
Alexios
5
/dev/stdinoder /dev/stdoutkann verwendet werden, wenn Sie wirklich einen Eingabe- / Ausgabestream möchten. Beachten Sie, dass es sich um einen Stream handelt, mit dem Programme, die in einer Datei suchen möchten, möglicherweise nicht ordnungsgemäß arbeiten, wie dies bei -(z. B. ffmpeg)
Lekensteyn,
3
Im Fall von bash, der Bindestrich wird von der Shell interpretiert. Weitere Informationen finden Sie im Advanced Bash-Scripting Guide - Kapitel 3. Sonderzeichen. Suchen Sie dann nach dem Text [Bindestrich] oder "Weiterleitung von / nach stdin oder stdout". Mit können bashSie den Bindestrich an den meisten Stellen verwenden, an denen ein Dateiname erwartet wird. Es ist eine offensichtliche Ergänzung zu <| > IMHO
bsd
4
Ich bin nicht davon überzeugt, dass dies der Fall ist. Zuerst catGriffe -(siehe Manpage). Eine in die Shell eingebaute Version von catmight oder might not, aber das ist nicht unbedingt die gesamte Shell. Wenn die Shell behandelt würde -, könnte man auch Echo sagen -und es würde sich zu etwas anderem ausdehnen. Stattdessen wird nur ein Gedankenstrich ausgegeben (nicht /dev/stdinoder /proc/self/fd/0). Und echo test > -erstellt einfach eine Datei mit dem Namen -, damit sie dort auch nicht verarbeitet wird. Oh, und die Seite, die Sie aufgelistet haben, sagt nicht, dass sie von der Shell verwaltet wird , sondern dass Sie sie mit catund verwenden diffkönnen. Beide verstehen Bindestriche explizit.
Alexios
13

In diesem Fall ist das -eigentlich ziemlich nutzlos, vorausgesetzt, Sie betreiben Linux:

GNU tar (die Version unter Linux) akzeptiert seine Eingabe standardmäßig aus der Standardeingabe. Wenn Sie dieses Verhalten nicht möchten und den Dateinamen als Befehlszeilenargument übergeben möchten, müssen Sie das Flag angeben f:

tar xf filename

Das ist also dasselbe wie

tar x < filename

Oder, wenn die Eingabe wie in Ihrem Beispiel gzippt ist:

gzip -dc filename | tar x

Es ist nicht sinnvoll, das fFlag hier überhaupt anzugeben , aber da es angegeben wurde, muss der Dateiname angegeben werden, -um anzuzeigen, dass wir von der Standardeingabe lesen möchten (siehe andere Antwort). Um es zu wiederholen, dies ist überflüssig und etwas seltsam.

Darüber hinaus kann die obige Zeile vereinfacht werden, da GNU tar angewiesen werden kann, die Eingabe durch gzipAngabe des zFlags durch sich selbst zu streamen :

tar xfz filename

- Sie müssen nicht gzipexplizit anrufen .

Konrad Rudolph
quelle
1
Hinweis: Nicht jeder tarhat eine zOption.
Liori
2
Die meisten anderen Betriebssysteme als Linux verwenden taraus historischen Gründen standardmäßig das erste Bandlaufwerk.
Gilles
1
@Gilles und BSD und OS X,…. Aber ich bin neugierig: was andere Systeme außer in ein paar alten Mainframes noch verwenden , eine solche Version (welche andere Systeme als Mainframes haben sogar haben ein Bandlaufwerk)?
Konrad Rudolph
1
@KonradRudolph Alle drei Haupt-BSDs verwenden standardmäßig ein Bandlaufwerk ( /dev/sa0unter FreeBSD 9.0, /dev/rst0NetBSD 6.0 und OpenBSD 5.1). AIX 7.1 verwendet standardmäßig /dev/rmt0. MINIX3 ist standardmäßig auf /dev/sa0. (Ich habe jeweils die neueste Betriebssystemversion überprüft, dies sind keine „alten Mainframes“.) Solaris kann über eine Datei konfiguriert werden, in /etcder meines Erachtens standardmäßig ein Bandlaufwerk gespeichert ist. GNU tar, Schilling tar, OSX und BusyBox sind standardmäßig stdin / stdout.
Gilles
1
@Gilles - Ich habe aus offensichtlichen Gründen die tarStandardeinstellung für das zweite Bandlaufwerk wiederhergestellt . :)
David Harkness