teer und seine schlüsselbuchstaben: ist es ein fehler oder eine funktion?

18

Ich frage mich, ob sich diese beiden Befehle unterscheiden (dh nur die Reihenfolge ihrer Optionen ist unterschiedlich):

  1. tar -zxvf foo.tar.gz
  2. tar -zfxv foo.tar.gz

Der erste lief perfekt, aber der zweite sagte:

tar: You must specify one of the `-Acdtrux' or `--test-label'  options
Try `tar --help' or `tar --usage' for more information.

Und Teer mit --test-labelund -zfxvsagte:

tar (child): xv: Cannot open: No such file or directory
tar (child): Error is not recoverable: exiting now
tar: Child returned status 2
tar: Error is not recoverable: exiting now

Dann habe ich mir das Handbuch für den Teer angesehen und festgestellt, dass -fam Ende alle Beispiele den Schalter verwenden !!

AFAICT gibt es keine Notwendigkeit für diese Einschränkung, oder gibt es ?! denn aus meiner sicht sollten schalter umsonst bestellt werden.

Khikho
quelle
2
@schily Ihre "Korrektur" an den Befehlszeilen verdeckt, welchen Befehl er tatsächlich eingegeben hat. Ein führender Gedankenstrich ändert das Verhalten von GNU tar, um einen anderen Argument-Parser zu verwenden. Ohne Bindestrich (und damit den traditionellen Argument-Parser) hätte der zweite Befehl funktioniert.
Random832
Der Delta-Ausdruck aus dem Web-System hat mir mitgeteilt, dass Sie oder jemand zuvor das - hinzugefügt hat. Deshalb habe ich es wieder entfernt, damit es mit dem übereinstimmt, was das System aus dem OP gemeldet hat. Aber wenn Sie Recht haben gtar option parsing, haben Sie einen weiteren Grund gefunden, warum Sie gtar nicht verwenden.
Schily
1
-ferwartet, dass der Dateiname folgt. In Ihrer zweiten Version haben Sie angegeben -fxv, was - für tar - bedeutet, dass der Dateiname "xv" ist.
Rolf
1
Obligatorische XKCD .
Pavel

Antworten:

11

Wenn Sie sich Ihre Fehlermeldung ansehen, ist es offensichtlich, dass Sie sie nicht verwendet haben, tarsondern eher gtar.

Im Allgemeinen kann dies helfen, Dinge zu verstehen:

  • tarbenötigt normalerweise immer ein Dateiargument. Wenn es fehlt, liest / schreibt es von / auf das Standard-Real-Bandgerät des Systems. staränderte dies 1982, um standardmäßig stdin / stdout zu verwenden, und einige andere tar-Implementierungen (z. B. gtar) folgten kürzlich diesem Beispiel.

  • tarimplementiert nicht die führenden -Optionen für Optionen, die key lettersim Fall des Befehls tar aufgerufen werden . Einige Implementierungen wurden später aus Gründen der -Benutzerfreundlichkeit als "no-op" -Schlüssel hinzugefügt , Sie können sich jedoch nicht darauf verlassen.

  • Die Art und Weise, wie tardie Argumente analysiert werden (insbesondere das Argument der Archivdatei), ist sehr riskant. Ich habe viele tar-Archive gesehen, die eine der Dateien zerstört haben, die sich im Archiv befinden sollten, da das zugehörige Dateiargument als tar-Archivdatei verwendet wurde. starAus diesem Grund kann star"f" (wenn nativ als " aufgerufen" ) nicht mit anderen Optionen verknüpft werden. Wenn staraufgerufen wird tar, implementiert es die Kompatibilität mit der Befehlszeile tar, behandelt das Argument für den Schlüsselbuchstaben "f" jedoch anders: Das Argument ist nur zulässig, wenn es sich auf eine echte Gerätedatei bezieht oder wenn die Datei (im Schreibmodus) noch nicht vorhanden ist .

Ich empfehle, die riskante ursprüngliche tar-Befehlszeile zu vermeiden und lieber die moderne, sicherere Befehlszeilensyntax zu verwenden, mit der Sie arbeiten star.

Wegen der problematischen Kommandozeilensyntax targab es tar warsAnfang der 1990er Jahre die sogenannten . Infolgedessen wurde das Programm pax(lateinisch für "Frieden" in den Teerkriegen) erstellt und standardisiert. paxPopularität erlangte es jedoch nicht, da seine Syntax weniger riskant, aber auch weniger intuitiv ist als die tar-Syntax. Ein anderes Problem kann sein, dass gpaxes mehr oder weniger ungepflegt ist.

schily
quelle
3
Die Teerkriege sind vorbei. guntar hat gewonnen.
Joshua
2
Wenn Sie Recht hatten, warum kopieren alle Tar-Implementierungen Features von star?
Schily
1
Übrigens: Die Teerkriege waren ein Kampf zwischen tarund cpio.
Schily
2
OK, so scheint es , star‚s -f"$file"ist auch (zusätzlich zu ind) ein Problem mit Dateinamen beginnen mit =. Also muss man es entweder -f="$file"oder schreiben -f "$file". Ich bin nicht sicher, ob ich Ihre Star-Option als sicherer oder moderner bezeichnen würde .
Stéphane Chazelas
3
-longStyle Long-Optionen sind mit Condensed -xyzShort-Optionen oder nicht kompatibel -xarg. Aus diesem Grund erfordern lange Optionen im X11-Stil, dass kurze Optionen getrennt ( -x -y, nicht -xy) und Optionsargumente in getrennten Argumenten ( xterm -n foo, nicht xterm -nfoo) angegeben werden. Und deshalb gibt es einen zusätzlichen Gedankenstrich in GNU-Long-Optionen, um die mögliche Verwechslung mit Short-Optionen zu beseitigen, und warum GNU-Long-Optionen ein besseres Design sind. Sie können nur -fookoexistieren, -x -y -xywenn Sie sehr vorsichtig sind, um Überschneidungen zu vermeiden.
Stéphane Chazelas
55

Die Reihenfolge der Schalter ist frei, es -fgibt jedoch ein obligatorisches Argument für die Datei, tardie gelesen / geschrieben werden soll.

Du könntest es tun

tar -zf foo.tar.gz -xv

und das wird funktionieren und erfordert eine unspezifische Reihenfolge von Schaltern.

So funktionieren alle Befehle mit Optionen, die Argumente haben.

wurtel
quelle
5
Tar funktioniert nicht wie andere Befehle, da es einen anderen, viel älteren Befehlszeilenparser verwendet - den gleichen, der im Befehl "ar" und im alten (vor POSIX) Befehl "ps" verwendet wird.
Schily
1
Vielen Dank dafür. Die ausgewählte Antwort war zwar gründlich, erlaubte mir jedoch nicht wirklich zu erkennen, was genau das Problem war. Rückblickend scheint es aus der Fehlermeldung offensichtlich zu sein, dass tar versucht hat, die Datei 'xv' zu lesen
Josh Rumbut,
1
Ich glaube, Sie können es auch als deklarieren -f=./myfile, das heißt, f nimmt einen Wert an, es ist kein Flag, es ist eine Eingabe.
ThorSummoner
14

Traditionell tar Optionen sind mehr oder weniger „ um frei“ (die Reihenfolge der fund bOptionen machen unabhängig davon , ob beide angegeben werden). Die Verwendung eines führenden Bindestrichs führt jedoch dazu, dass GNU tar die Optionen auf eine Weise analysiert, die als konsistenter mit anderen Befehlen angesehen wird. Wenn Sie eine Option angeben, für die ein Argument erforderlich ist (z. B. der Dateiname für f), wird der Rest des "Wortes" sofort verbraucht. falls vorhanden, als Argument (traditionell verwendet tar das nächste Wort als Dateiname / Blockgröße, wenn foder bangegeben wird). In Ihrem Fall wurde "xv" als Dateiname verwendet.

Für die Portabilität kann dieses Verhalten jedoch nicht herangezogen werden. Um eine maximale Portabilität zu erzielen, sollten Sie die Verwendung eines Bindestrichs vermeiden, immer den fletzten und immer ein Leerzeichen zwischen fund dem Dateinamen einfügen. Dies ist jedoch eine Vereinfachung, die sich aufteilt, wenn Sie die bOption oder generell eine Candere Option (z. B. ) fbenötigen, für die ein Argument erforderlich ist.

Dies ist im Abschnitt "Die drei Optionsstile" des Tar-Handbuchs dokumentiert . Einige andere Implementierungen (zB FreeBSD) bezeichnen die alten Optionen als "gebündeltes Optionswort". Und natürlich unterstützen einige Implementierungen möglicherweise nur diese Art von Option und ignorieren möglicherweise einen Gedankenstrich, wenn er enthalten ist. Dies ist die einzige Form des Aufrufs, die in der Single Unix-Spezifikation angegeben ist, und funktioniert daher garantiert auf fast allen Systemen.

Random832
quelle
2
Beachten Sie, dass einige Implementierungen andere Optionen mit Argumenten unterstützen (wie Cin BSD oder GNU tar. Schily tar unterstützt dies als -C, aber nicht als C, alle unterstützen dies als -C).
Stéphane Chazelas
0

In Teer ist der - in den Schaltern vor vielen Jahren veraltet und nicht mehr notwendig. Eigentlich hat Tar dir das gesagt, aber das tut er nicht mehr.

ie:
tar zxvf foo.tar.gz
tar zfxv foo.tar.gz

Both of these work fine without the -.
Paul
quelle