Warum ist die spezifische Reihenfolge der Optionen für den Befehl tar wichtig?

7

Ich habe den tarBefehl ausprobiert, ein Archiv mit .tarErweiterung zu erstellen.

Bitte schauen Sie sich die folgenden Befehle an, die ich ausprobiert habe:

$ ls
abc.jpg  hello.jpg  xjf.jpg
$ tar -cfv test.tar *.jpg
tar: test.tar: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
$ ls
abc.jpg  hello.jpg  v  xjf.jpg
$ rm v
$ ls
abc.jpg  hello.jpg  xjf.jpg
$ tar -cvf test.tar *.jpg
abc.jpg
hello.jpg
xjf.jpg
$ ls
abc.jpg  hello.jpg  test.tar  xjf.jpg

Warum gibt es unterschiedliche Antworten mit unterschiedlichen Optionen? dh -cfvvs cvf.
Nach dem, was ich in Bash-Skripten gelernt habe, spielt diese Optionssequenz keine Rolle.

Edward Torvalds
quelle
Beachten Sie, dass dies nur für einige tarImplementierungen gilt (z. B. nicht für Solaris).
Stéphane Chazelas
2
Im Allgemeinen ist die Reihenfolge der Optionen für Befehle von Bedeutung, insbesondere wenn einige der Optionen Werte annehmen. GNU verwischt dies bis zu einem gewissen Grad, es sei denn, Sie haben POSIXLY_CORRECT in der Umgebung festgelegt, indem Sie Optionen vor Nichtoptionen neu anordnen. Im Allgemeinen gehen Optionen jedoch Nichtoptionen und Auftragsangelegenheiten voraus. Ordnung ist nicht immer wichtig, aber es ist oft (oder ist das nur "manchmal"?) Wichtig.
Jonathan Leffler
@ JonathanLeffler - im Allgemeinen manchmal.
Mikeserv

Antworten:

11

Wie @jcbermu sagte, ist für die meisten Programme und in den meisten Fällen die Reihenfolge der Befehlszeilenflags nicht wichtig. Einige Flags erwarten jedoch einen Wert. Insbesondere -flautet die Flagge von tar :

  -f, --file ARCHIVE
       use archive file or device ARCHIVE

Also, tarerwartet -feinen Wert zu haben , und dieser Wert wird der Name des tarfile es schafft. Um beispielsweise alle .jpgDateien zu einem aufgerufenen Archiv hinzuzufügen foo.tar, würden Sie ausführen

tar -f foo.tar *jpg

Was du gelaufen bist war

tar -cfv test.tar *.jpg

tarversteht das als "create ( -c) ein Archiv namens v( -fv), das Dateien test.tarund alle Endungen in enthält .jpg.

Wenn Sie dagegen ausführen tar -cvf test.tar *.jpg, wird test.tarder Name des Archivs und *jpgdie Liste der Dateien verwendet.

terdon
quelle
1
Nur um genau zu sein: -csteht eigentlich für create, nicht compress. Jedenfalls eine gute Antwort.
Erathiel
1
Tatsächlich tarverarbeitet GNU seine Befehlszeilenargumente wie ein Skript - und daher ist ihre Reihenfolge im Allgemeinen sehr wichtig. Wenn sie zufällig verarbeitet würden, würde dies --checkpointDinge wie Skripte oder mehrbändige Archive zur Pflicht machen , und selbst einfache Dinge wie: set file[1234]; for f do shift; set -- "$@" "-C$PWD/dir${f#file}" -x "$f"; done; tar -c . | tar "$@"würden nicht funktionieren.
Mikeserv
Ihre Bearbeitung ist besser, verfehlt aber immer noch die Marke, denke ich: Die Reihenfolge der verschiedenen Optionen im Verhältnis zueinander sollte keine Rolle spielen, es sei denn, die Optionen schließen sich gegenseitig aus und eine solche Option wird dokumentiert, um alle inkompatiblen Optionen davor zu überschreiben. Wenn eine Option mit Optionsargumenten wiederholt wird, sollten die Kombinationen aus Option und Optionsargument in der in der Befehlszeile angegebenen Reihenfolge interpretiert werden. Grundsätzlich ist die Reihenfolge von Bedeutung, sobald eine Option den Betrieb einer anderen beeinflusst. Zu den gängigen Beispielen gehören die -[if]Optionen zu mvund / oder rm.
Mikeserv
Und natürlich wird die Reihenfolge, in der die --Flagge in einer Befehlszeile relativ zu anderen angezeigt wird, wahrscheinlich immer eine große Rolle spielen.
Mikeserv
@mikeserv um Himmels willen, lesen Sie, was ich sage: " Für die meisten Programme und in den meisten Fällen ist die Reihenfolge der Befehlszeilenflags nicht wichtig."
Terdon
9

Die Reihenfolge spielt keine Rolle, solange die Option keinen Wert benötigt. In Ihrem Fall muss -f einen Dateinamen angeben.

Im ersten Fall ( tar -cfv ) glaubt der Befehl, dass der Ausgabedateiname v ist, weil er nach -f steht .

jcbermu
quelle
1
Und Sie erhalten die Fehlermeldung, die Sie erhalten, weil versucht wird, test.tarsie dem Archiv hinzuzufügen .
Mark
@ Mark ... test.tar, die nicht existiert noch zum Zeitpunkt der Befehl daher eingegeben wird die Meldung « Keine solche Datei oder das Verzeichnis ». Nur pedant sein ;-).
5

Während andere darauf hingewiesen haben, dass es so behandelt wurde -c -f v, sollte ich beachten, dass dies nur geschieht, weil der Bindestrich verwendet wurde und dieses Verhalten nicht für alle Versionen von tar gilt. Im Legacy-Modus (kein Bindestrich) behandelt tar das erste Argument speziell, und ein "f" oder "b" darin verbraucht die nächsten vollständigen Wörter nach den Optionen (so tar cfb file.tar 20oder so tar cbf 20 file.tar). Für GNU tar finden Sie weitere Details in der vollständigen Texinfo-Dokumentation, indem Sie ausführen info tar styles.

Im Allgemeinen sollten Sie sich nicht auf eines der beiden Verhaltensweisen verlassen und immer f als letzte Option angeben und ein Leerzeichen zwischen diesem und dem Dateinamen einfügen. ( -bist nur in einigen Situationen wichtig, wenn auf physische Bandlaufwerke geschrieben wird, daher kann es für diese Diskussion ignoriert werden.)

Random832
quelle
Beachten Sie, dass dies auch für sh(und möglicherweise andere Pre-Getopt-Tools) gilt. sh -cf noglob 'echo test'funktioniert wie sh -f -c 'echo test'in der Bourne-Shell und Derivaten (und sh -ocC noglob 'echo test'wie sh -o noblob -C -c 'echo test'in den meisten Bourne-Derivaten). Beachten Sie auch, dass in einigen herkömmlichen tarImplementierungen tar -cfvdasselbe wie in tar -cvf.
Stéphane Chazelas