Chmod und -r + r

13

Ich habe versucht, den Befehl chmod in der falschen Reihenfolge aufzurufen. chmod file.txt -rDas hat aus irgendeinem Grund funktioniert. chmod file.txt +rAuf der anderen Seite weigerte sich zu arbeiten. Warum ist das? Aus welchem ​​Grund funktioniert ein Befehl und der andere nicht?

TestyTentacleLinux
quelle

Antworten:

18

Dies ist eine Eigenheit der Art und Weise, wie GNU chmod Eingaben verarbeitet, und ist nicht auf alle POSIX-kompatiblen chmod-Implementierungen übertragbar.

Beachten Sie, dass für die POSIX-chmod Coomand-Line-Syntax der Modus an erster Stelle stehen muss, ebenso wie für GNUchmod (Optionen sollten auch vor dem Modus stehen). Alles andere ist eine undokumentierte Implementierungs-Eigenheit.


Nun, warum es in dieser speziellen Implementierung passiert:

Im Handbuch wird angedeutet :

In der Regel ist jedoch " chmod a-w file" vorzuziehen, und chmod -w file(ohne das --) beschwert sich, wenn es sich anders verhält als " chmod a-w file".

Kurz gesagt, Optionen, die von analysiert werden, getoptwird ein vorangestelltes -. Wie in ls -a, aist eine Option. Die Langform ls --allhat allals Option. rm -rf(entspricht rm -r -f) hat beides rund fOptionen.

Alles andere ist ein Nicht-Options-Argument, das technisch als Operanden bezeichnet wird . Ich nenne diese Positionsargumente gerne , da ihre Bedeutung durch ihre relative Position bestimmt wird. In chmodist das erste Positionsargument der Modus und das zweite Positionsargument der Dateiname.

Optimalerweise sollte Mode nicht mit a führen -. Ist dies der Fall, sollten Sie --als Operanden erzwingen Parsen anstelle einer Option (dh Verwendung chmod a-w fileoder chmod -- -w filestatt chmod -w file. Dies wird auch vorgeschlagen , durch POSIX.


Wenn Sie sich den Quellcode ansehen , werden Sie feststellen, dass getopt zum Parsen von Befehlszeilenoptionen verwendet wird. Hier gibt es eine spezielle Behandlung für "falsche" Modi wie -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.  */

Nehmen Sie Ihr Beispiel:

  • chmod a-r file.txtwäre der robusteste Aufruf.
  • chmod +r file.txt funktioniert, weil das erste Argument positionsmäßig als Modus interpretiert wird.
  • chmod -r file.txtfunktioniert immer noch, weil das -rals kurze rOption interpretiert wird und in einem speziellen Gehäuse ist.
  • chmod -- -r file.txtist korrekt und funktioniert, weil der -rals Modus positionsmäßig interpretiert wird. Dies unterscheidet sich vom Fall ohne, --weil mit --dem -rnicht als Option gedeutet wird .
  • chmod file.txt -rfunktioniert immer noch, weil das -rals kurze rOption interpretiert wird und in einem speziellen Gehäuse ist. Optionen sind nicht positionsabhängig. Dies missbraucht technisch eine undokumentierte Eigenart.
  • chmod file.txt +rfunktioniert nicht, weil der +rein Operand ist, keine Option. Der erste Operand ( file.txt) wird als Modus interpretiert ... und kann nicht analysiert werden.
Bob
quelle
4
Dies kann interessante Konsequenzen haben, wenn Sie beispielsweise eine Datei mit dem Namen haben a+rwxund so etwas tun chmod * +rund die a+rwxDatei zufällig an erster Stelle in der Glob-Erweiterung steht.
Jörg W Mittag
1
Oder eine Datei mit dem Namen "-rf" im Fall von "rm *".
Edheldil
@Edheldil Ja, Sie haben Recht. Dies scheint etwas zu sein, das
behoben
Beachten Sie, dass die OP-Syntax nicht POSIX lautet. Man7.org/linux/man-pages/man1/getopt.1.html#SCANNING_MODES
Steven Penny
@StevenPenny Das ist irrelevant. Erstens ist die verknüpfte Manpage Abschnitt 1, dh der getopt Befehl , nicht die Bibliotheksroutine in Abschnitt 3 . Zweitens bezieht sich dies auf die optstring, dh die Liste der akzeptierten Optionen (in der chmodQuelle optstringist festgelegt auf "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"). Der verknüpfte Abschnitt "SCANNING MODES" hat nichts mit dem Argumentarray zu tun argv, das die an das Programm übergebenen Argumente enthält.
Bob