Chmod dan -r + r

13

Saya telah mencoba memanggil perintah chmod dengan urutan yang salah. chmod file.txt -rIni berhasil karena beberapa alasan. chmod file.txt +rDi sisi lain menolak bekerja. Kenapa ini? Untuk alasan apa satu perintah bekerja, dan yang lainnya tidak?

TestyTentacleLinux
sumber

Jawaban:

18

Ini adalah kekhasan dari bagaimana chmod GNU menangani input, dan tidak portabel untuk semua implementasi chmod yang kompatibel dengan POSIX.

Perhatikan bahwa POSIXchmod coomand-line sintaks membutuhkan modus untuk datang pertama, seperti halnya GNUchmod (pilihan harus datang sebelum mode, juga). Yang lainnya adalah kekhilafan implementasi yang tidak berdokumen.


Sekarang, mengapa hal itu terjadi dalam implementasi khusus ini:

Diisyaratkan di dalam manual :

Namun, biasanya, ' chmod a-w file' lebih disukai, dan chmod -w file(tanpa --) mengeluh jika berperilaku berbeda dari apa yang chmod a-w fileakan dilakukan.

Secara singkat, opsi yang diuraikan oleh getoptdiawali dengan a -. Seperti dalam ls -a, aadalah opsi. Bentuk panjang ls --allmemiliki allopsi. rm -rf(setara dengan rm -r -f) memiliki keduanya rdan fopsi.

Yang lainnya adalah argumen non-opsi, secara teknis disebut operan . Saya suka menyebut argumen posisi ini , karena maknanya ditentukan oleh posisi relatif mereka. Dalam chmod, argumen posisi pertama adalah mode dan argumen posisi kedua adalah nama file.

Secara optimal, mode tidak boleh mengarah dengan -. Jika ya, Anda harus menggunakan --parsing sebagai operan alih-alih opsi (yaitu penggunaan chmod a-w fileatau chmod -- -w filealih-alih chmod -w file. Ini juga disarankan oleh POSIX.


Jika Anda melihat kode sumber , Anda akan melihatnya menggunakan getopt untuk mengurai opsi baris perintah. Di sini, ada penanganan khusus untuk mode 'salah' seperti -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.  */

Ambil contoh Anda:

  • chmod a-r file.txtakan menjadi doa yang paling kuat .
  • chmod +r file.txt berfungsi karena argumen pertama ditafsirkan secara posisi sebagai mode.
  • chmod -r file.txtmasih berfungsi karena -rdiartikan sebagai ropsi pendek dan khusus.
  • chmod -- -r file.txtbenar dan berfungsi karena -rposisi ditafsirkan sebagai mode. Ini berbeda dari kasus tanpa --karena dengan --itu -rtidak ditafsirkan sebagai pilihan .
  • chmod file.txt -rmasih berfungsi karena -rdiartikan sebagai ropsi pendek dan khusus. Opsi tidak bergantung pada posisi. Ini secara teknis menyalahgunakan kebiasaan yang tidak berdokumen.
  • chmod file.txt +rtidak berfungsi karena +roperan, bukan opsi. Operan pertama ( file.txt) ditafsirkan sebagai mode ... dan gagal diurai.
Bob
sumber
4
Ini dapat memiliki konsekuensi yang menarik jika Anda memiliki file bernama, misalnya, a+rwxdan melakukan sesuatu seperti chmod * +r, dan a+rwxfile tersebut menjadi yang pertama dalam ekspansi glob.
Jörg W Mittag
1
Atau file bernama "-rf" untuk "rm *".
Edheldil
@Edheldil Ya Anda benar. Ini sepertinya sesuatu yang harus diatasi (dan bug, sama seperti jika input tidak dibersihkan dengan benar.
TestyTentacleLinux
Perhatikan bahwa sintaks OP bukan POSIX man7.org/linux/man-pages/man1/getopt.1.html#SCANNING_MODES
Steven Penny
@ Svenvenenny Itu tidak relevan. Pertama, halaman manual yang terhubung adalah bagian 1, yaitu getopt perintah , bukan rutin perpustakaan di bagian 3 . Kedua, itu merujuk pada optstring, yaitu daftar opsi yang diterima (dalam chmodsumber optstringdiatur ke "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"). Bagian "SCANNING MODES" yang ditautkan tidak ada hubungannya dengan array argumen argv yang berisi argumen yang diteruskan ke dalam program.
Bob