Chmod e -r + r


13

Ho provato a chiamare il comando chmod nell'ordine sbagliato. chmod file.txt -rQuesto ha funzionato per qualche motivo. chmod file.txt +rD'altro canto, ha rifiutato di funzionare. Perchè è questo? Per quale motivo funziona un comando e l'altro no?

Risposte:


18

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.

4
Ciò può avere conseguenze interessanti se si dispone di un file denominato, ad esempio, a+rwxe si fa qualcosa di simile chmod * +r, e il a+rwxfile viene prima nell'espansione glob.
Jörg W Mittag,

1
O un file chiamato "-rf" in caso di "rm *".
Edheldil,

@Edheldil Sì hai ragione. Sembra qualcosa che dovrebbe essere risolto (e un bug, proprio come se l'input non fosse stato disinfettato correttamente.
TestyTentacleLinux


@StevenPenny È irrilevante. Innanzitutto, la manpage collegata è la sezione 1, ovvero il getopt comando , non la routine della libreria nella sezione 3 . In secondo luogo, si riferisce a optstring, ovvero all'elenco di opzioni accettate (in chmodorigine optstringè impostato su "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"). La sezione "MODALITÀ DI SCANSIONE" collegata non ha nulla a che fare con l' array di argomenti argv che contiene gli arg passati al programma.
Bob,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.