web-dev-qa-db-fra.com

Chmod et -r + r

J'ai essayé d'appeler la commande chmod dans le mauvais ordre. chmod file.txt -r Cela a fonctionné pour une raison quelconque. chmod file.txt +r D'autre part refusé de travailler. Pourquoi est-ce? Pour quelle raison une commande fonctionne-t-elle et l'autre pas?

13
TestyTentacleLinux

C'est une bizarrerie de savoir comment GNU chmod gère les entrées et n'est pas portable pour toutes les implémentations de chmod compatibles POSIX.

Notez que la syntaxe POSIX chmod coomand-line exige que le mode apparaisse en premier, de même que GNU chmod (les options doivent aussi venir avant le mode). Tout le reste est une bizarrerie d'implémentation non documentée.


Maintenant, sur pourquoi cela se produit dans cette implémentation particulière:

C'est indiqué dans le manuel :

Cependant, ‘chmod a-w file 'est préférable, et chmod -w file (sans le --) se plaint s’il se comporte différemment de ce que ferait ___chmod a-w file'.

En bref, les options analysées par getopt portent le préfixe -. Comme dans ls -a, a est une option. La forme longue ls --all a all en option. rm -rf (équivalent à rm -r -f) a les deux options r et f.

Tout le reste est un argument sans option, appelé techniquement des opérandes . J'aime appeler ces arguments positionnels , car leur signification est déterminée par leur position relative. Dans chmod, le premier argument de position est le mode et le second argument de position est le nom du fichier.

De manière optimale, le mode ne devrait pas être précédé d'un -. Si tel est le cas, vous devez utiliser -- pour forcer l'analyse en tant qu'opérande au lieu d'une option (c'est-à-dire, utilisez chmod a-w file ou chmod -- -w file au lieu de chmod -w file. C'est également suggéré par POSIX.


Si vous regardez le code source , vous remarquerez qu'il utilise getopt pour analyser les options de la ligne de commande. Ici, il existe une gestion spéciale pour les modes "incorrects" comme -w:

    case 'r':
    case 'w':
    case 'x':
    case 'X':
    case 's':
    case 't':
    case 'u':
    case 'g':
    case 'o':
    case 'a':
    case ',':
    case '+':
    case '=':
    case '0': case '1': case '2': case '3':
    case '4': case '5': case '6': case '7':
      /* Support nonportable uses like "chmod -w", but diagnose
         surprises due to umask confusion.  Even though "--", "--r",
         etc., are valid modes, there is no "case '-'" here since
         getopt_long reserves leading "--" for long options.  */

Prenons votre exemple:

  • chmod a-r file.txt serait l'invocation la plus robuste .
  • chmod +r file.txt fonctionne parce que le premier argument est interprété positionnellement comme le mode.
  • chmod -r file.txt fonctionne toujours car le -r est interprété comme une option r courte et une casse spéciale.
  • chmod -- -r file.txt est correct et fonctionne car le -r est interprété positionnellement comme le mode. Ceci diffère du cas sans -- car avec -- le -r n'est pas interprété comme une option .
  • chmod file.txt -r fonctionne toujours car le -r est interprété comme une option r courte et une casse spéciale. Les options ne dépendent pas de la position. Cela abuse techniquement d'un caprice non documenté.
  • chmod file.txt +r ne fonctionne pas car +r est un opérande, pas une option. Le premier opérande (file.txt) est interprété comme un mode ... et ne parvient pas à être analysé.
18
Bob