tar et ses lettres-clés: est-ce un bug ou une fonctionnalité?

18

Je me demande de demander la différence de ces deux commandes (c'est-à-dire que seul l'ordre de leurs options est différent):

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

Le premier a fonctionné parfaitement mais le second a dit:

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

Et goudron avec --test-labelet -zfxvdit:

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

Ensuite, j'ai regardé le manuel de tar et j'ai réalisé que tous les exemples qu'il y avait à l'aide de switch -fà la fin !!

AFAICT il n'y a pas besoin de cette restriction, ou est-ce?! parce qu'à mon avis, les commutateurs doivent être commandés gratuitement.

khikho
la source
2
@schily votre "correction" des lignes de commande a obscurci la commande qu'il a réellement tapée. Un tiret de tête modifie le comportement de GNU tar pour utiliser un analyseur d'arguments différent. Sans tiret (et donc avec l'analyseur d'arguments traditionnel), la deuxième commande aurait fonctionné.
Random832
L'impression delta du système Web m'a dit que vous ou quelqu'un avant d'ajouter le -, je l'ai donc retiré à nouveau pour correspondre à ce que le système m'a dit provenir de l'OP. Mais si vous avez raison gtar option parsing, vous avez découvert une autre raison de ne pas utiliser gtar.
schily
1
-fs'attend à ce que le nom de fichier suive. Dans votre deuxième version, vous avez spécifié -fxvce qui - pour tar - signifie que le nom de fichier est "xv".
Rolf
1
XKCD obligatoire .
Pavel

Réponses:

11

En regardant votre message d'erreur, il est évident que vous ne l'avez pas utilisé tarmais plutôt gtar.

En général, cela peut aider à comprendre les choses:

  • tara normalement toujours besoin d'un argument de fichier. S'il est manquant, il lira / écrit depuis / vers le véritable périphérique de bande par défaut du système. stara changé cela en 1982 pour utiliser stdin / stdout par défaut et d'autres implémentations tar (par exemple gtar) ont récemment suivi cet exemple.

  • tarn'implémente pas le début -des options appelées key lettersdans le cas de la commande tar. Certaines implémentations ont été ajoutées par la suite -sous la forme d'une lettre clé sans opération pour la commodité des utilisateurs, mais vous ne pouvez pas vous y fier.

  • La façon d' taranalyser ses arguments (en particulier l'argument du fichier archive) est très risquée. J'ai vu de nombreuses archives tar qui ont détruit l'un des fichiers qui devraient être dans l'archive car l'argument de fichier associé a été pris comme fichier d'archive tar. starpour cette raison (si appelé nativement as star) ne permet pas de concaténer "f" avec d'autres options. Si starest appelé, taril implémente la compatibilité de ligne de commande avec tar, mais gère toujours l'argument de la lettre clé "f" différemment: l'argument n'est autorisé que s'il fait référence à un fichier de périphérique réel ou lorsque (en mode écriture) le fichier n'existe pas encore .

Je recommande d'éviter la ligne de commande tar risquée d'origine et plutôt d'utiliser la syntaxe de ligne de commande plus sûre moderne que vous obtenez star.

En raison de la syntaxe problématique de la ligne de commande de tar, il y avait ce qu'on appelle tar warsau début des années 1990. En conséquence, le programme pax(latin pour «paix» dans les guerres de goudron) a été créé et standardisé. paxcependant n'a pas gagné en popularité car sa syntaxe est moins risquée mais aussi moins intuitive que la syntaxe tar. Un autre problème peut être gpaxplus ou moins non entretenu.

schily
la source
3
Les guerres de goudron sont terminées. guntar a gagné.
Joshua
2
Si vous aviez raison, pourquoi toutes les implémentations tar copient-elles les fonctionnalités star?
schily
1
BTW: les guerres de goudron ont été une bataille entre taret cpio.
schily
2
OK, il semble donc star« s -f"$file"est également (en plus ind) un problème avec les noms de fichiers commençant par =. Il faut donc l'écrire soit -f="$file"ou -f "$file". Je ne suis pas sûr d'appeler votre option étoile plus sûre ou moderne .
Stéphane Chazelas
3
-longles options longues de style sont incompatibles avec les -xyzoptions courtes condensées ou -xarg. C'est pourquoi les options longues de style X11 nécessitent que les options courtes soient séparées ( -x -y, pas -xy) et les arguments d'option sur des arguments séparés ( xterm -n foo, non xterm -nfoo). Et c'est pourquoi il y a un tiret supplémentaire dans les options longues GNU, pour éliminer la confusion possible avec les options courtes, et pourquoi les options longues de style GNU sont une meilleure conception. Vous ne pouvez -foocoexister qu'avec -x -y -xysi vous faites très attention à éviter les chevauchements.
Stéphane Chazelas
55

L'ordre des commutateurs est libre, mais -fa un argument obligatoire qui est le fichier qui tarva lire / écrire.

Vous pourriez faire

tar -zf foo.tar.gz -xv

et cela fonctionnera, et a votre exigence d'un ordre non spécifique de commutateurs.

C'est ainsi que fonctionnent toutes les commandes qui ont des options qui ont des arguments.

gémir
la source
5
Tar ne fonctionne pas comme les autres commandes car il utilise un analyseur de ligne de commande beaucoup plus ancien - le même qui est utilisé dans la commande "ar" et l'ancienne commande (pré-POSIX) "ps".
schily
1
Merci pour cela, la réponse choisie, bien que approfondie, ne m'a pas vraiment permis de voir quel était précisément le problème. Rétrospectivement, il semble évident d'après le message d'erreur indiquant que tar essayait de lire le fichier 'xv'
Josh Rumbut
1
Je pense que vous pouvez également le déclarer comme -f=./myfile, c'est-à-dire que f prend une valeur, ce n'est pas un drapeau, c'est une entrée.
ThorSummoner
14

Traditionnellement, les options de tar sont plus ou moins "sans commande" (l'ordre des options fet bimporte peu si les deux sont spécifiées). L'utilisation d'un tiret de tête, cependant, oblige GNU tar à analyser les options d'une manière considérée comme plus cohérente avec d'autres commandes, où la spécification d'une option qui nécessite un argument (tel que le nom de fichier pour f) consommera immédiatement le reste du "mot", le cas échéant, comme argument (traditionnellement, tar utilise le mot suivant comme nom de fichier / taille de bloc lorsque fou best spécifié). Dans votre cas, il a pris "xv" comme nom de fichier.

Cependant, ce comportement ne peut pas être invoqué pour la portabilité. Pour une portabilité maximale, vous devez éviter d'utiliser un tiret, toujours mettre en fdernier et toujours mettre un espace entre fet le nom de fichier. C'est, cependant, une simplification qui tombe en panne si vous avez besoin de l' boption ou en général toute option (telle que C) autre que fcelle qui nécessite un argument.

Ceci est documenté dans la section du manuel de tar "Les trois styles d'options" . Certaines autres implémentations (par exemple FreeBSD) se réfèrent aux anciennes options de style comme un "mot d'option groupé". Et bien sûr, certaines implémentations peuvent uniquement prendre en charge ce type d'option, et peuvent ou non ignorer un tiret si elles sont incluses. Il s'agit de la seule forme d'invocation spécifiée dans la spécification Unix unique et donc garantie de fonctionner sur presque tous les systèmes.

Aléatoire832
la source
2
Notez que certaines implémentations prennent en charge d'autres options avec des arguments (comme Cdans BSD ou GNU tar. Schily tar la prend en charge en tant que -C mais pas en C, toutes la prend en charge en tant que -C).
Stéphane Chazelas
0

Dans le goudron, le - dans les commutateurs est obsolète depuis de nombreuses années et n'est plus nécessaire. Le goudron vous le disait, mais ce n'est plus le cas.

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

Both of these work fine without the -.
Paul
la source