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, getopt
wird ein vorangestelltes -
. Wie in ls -a
, a
ist eine Option. Die Langform ls --all
hat all
als Option. rm -rf
(entspricht rm -r -f
) hat beides r
und f
Optionen.
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 chmod
ist 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 file
oder chmod -- -w file
statt 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.txt
wäre der robusteste Aufruf.
chmod +r file.txt
funktioniert, weil das erste Argument positionsmäßig als Modus interpretiert wird.
chmod -r file.txt
funktioniert immer noch, weil das -r
als kurze r
Option interpretiert wird und in einem speziellen Gehäuse ist.
chmod -- -r file.txt
ist korrekt und funktioniert, weil der -r
als Modus positionsmäßig interpretiert wird. Dies unterscheidet sich vom Fall ohne, --
weil mit --
dem -r
nicht als Option gedeutet wird .
chmod file.txt -r
funktioniert immer noch, weil das -r
als kurze r
Option interpretiert wird und in einem speziellen Gehäuse ist. Optionen sind nicht positionsabhängig. Dies missbraucht technisch eine undokumentierte Eigenart.
chmod file.txt +r
funktioniert nicht, weil der +r
ein Operand ist, keine Option. Der erste Operand ( file.txt
) wird als Modus interpretiert ... und kann nicht analysiert werden.
a+rwx
und so etwas tunchmod * +r
und diea+rwx
Datei zufällig an erster Stelle in der Glob-Erweiterung steht.getopt
Befehl , nicht die Bibliotheksroutine in Abschnitt 3 . Zweitens bezieht sich dies auf dieoptstring
, dh die Liste der akzeptierten Optionen (in derchmod
Quelleoptstring
ist festgelegt auf"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
). Der verknüpfte Abschnitt "SCANNING MODES" hat nichts mit dem Argumentarray zu tunargv
, das die an das Programm übergebenen Argumente enthält.