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?

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.

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


@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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.