Questa è una stranezza di come GNU chmod gestisce l'input e non è portatile per tutte le implementazioni chmod compatibili con POSIX.
Nota che la sintassi della riga di comando POSIX chmodrichiede che la modalità venga prima, così come GNUchmod (anche le opzioni dovrebbero venire prima della modalità). Qualsiasi altra cosa è una stranezza dell'implementazione non documentata.
Ora, sul perché accade in questa particolare implementazione:
È accennato nel manuale :
In genere, tuttavia, " chmod a-w file" è preferibile e chmod -w file(senza il --) si lamenta se si comporta diversamente da ciò che " chmod a-w file" farebbe.
In breve, le opzioni analizzate da getoptsono precedute da a -. Come in ls -a, aè un'opzione. La forma lunga ls --allha allcome opzione. rm -rf(equivalente a rm -r -f) ha sia re fopzioni.
Tutto il resto è un argomento non opzionale, tecnicamente chiamato operandi . Mi piace chiamare questi argomenti posizionali , poiché il loro significato è determinato dalla loro posizione relativa. In chmod, il primo argomento posizionale è la modalità e il secondo argomento posizionale è il nome del file.
In modo ottimale, la modalità non dovrebbe condurre con a -. In tal caso, è necessario utilizzare --per forzare l'analisi come operando anziché come opzione (ovvero utilizzare chmod a-w fileo chmod -- -w fileanziché chmod -w file. Questo è suggerito anche da POSIX.
Se guardi il codice sorgente , noterai che usa getopt per analizzare le opzioni della riga di comando. Qui, c'è una gestione speciale per le modalità 'errate' come -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. */
Prendendo il tuo esempio:
chmod a-r file.txtsarebbe l' invocazione più solida .
chmod +r file.txt funziona perché il primo argomento è interpretato in modo posizionale come la modalità.
chmod -r file.txtfunziona ancora perché -rviene interpretato come run'opzione breve e con un case speciale.
chmod -- -r file.txtè corretto e funziona perché -rinterpretato in modo posizionale come la modalità. Ciò differisce dal caso senza --perché con --il -rnon è interpretato come un'opzione .
chmod file.txt -rfunziona ancora perché -rviene interpretato come run'opzione breve e con un case speciale. Le opzioni non dipendono dalla posizione. Ciò abusa tecnicamente di una stranezza non documentata.
chmod file.txt +rnon funziona perché +rè un operando, non un'opzione. Il primo operando ( file.txt) viene interpretato come una modalità ... e non riesce ad analizzare.
a+rwxe si fa qualcosa di similechmod * +r, e ila+rwxfile viene prima nell'espansione glob.