Chmod และ -r + r


13

ฉันได้ลองเรียกคำสั่ง chmod ในลำดับที่ไม่ถูกต้อง chmod file.txt -rสิ่งนี้ทำงานได้ด้วยเหตุผลบางอย่าง chmod file.txt +rในทางกลับกันปฏิเสธที่จะทำงาน ทำไมนี้ ด้วยเหตุผลอะไรคำสั่งหนึ่งทำงานและอื่น ๆ ไม่ได้?

คำตอบ:


18

นี่เป็นสิ่งที่แปลกประหลาดของวิธีที่ GNU chmod จัดการกับอินพุตและไม่สามารถพกพาไปยังการใช้งาน chmod ที่ใช้ POSIX ได้ทั้งหมด

โปรดทราบว่าไวยากรณ์ของPOSIXchmod coomand-line ต้องการโหมดที่จะมาก่อนเช่นเดียวกับGNUchmod (ตัวเลือกควรมาก่อนโหมดด้วย) สิ่งอื่นใดก็คือการเล่นโวหารที่ไม่มีเอกสาร


ทีนี้ลองดูว่าทำไมมันถึงเกิดขึ้นในการติดตั้งแบบนี้

มันบอกเป็นนัยในคู่มือ :

แม้ว่าโดยทั่วไปแล้ว ' chmod a-w file' จะดีกว่าและchmod -w file(ถ้าไม่มี--) จะบ่นว่ามันทำงานแตกต่างจากสิ่งที่chmod a-w fileจะทำหรือไม่

สั้น ๆ , ตัวเลือกแยกวิเคราะห์โดยจะมีคำนำหน้าด้วยgetopt -เช่นเดียวกับในls -a, aเป็นตัวเลือก แบบยาวls --allมีallเป็นตัวเลือก rm -rf(เทียบเท่าrm -r -f) มีทั้งตัวเลือกrและf

ทุกสิ่งทุกอย่างเป็นอาร์กิวเมนต์ที่ไม่ใช่ตัวเลือกที่เรียกว่าในทางเทคนิคตัวถูกดำเนินการ ฉันชอบที่จะเรียกข้อโต้แย้งตำแหน่งเหล่านี้ตามความหมายของพวกเขาถูกกำหนดโดยตำแหน่งญาติ ในchmodอาร์กิวเมนต์ตำแหน่งแรกคือโหมดและอาร์กิวเมนต์ตำแหน่งที่สองคือชื่อไฟล์

-อย่างดีที่สุดโหมดไม่ควรนำไปด้วย ถ้าเป็นเช่นนั้นคุณควรใช้--ในการบังคับให้แจงเป็นตัวถูกดำเนินการแทนตัวเลือก (เช่นใช้chmod a-w fileหรือchmod -- -w fileแทนที่จะchmod -w fileเป็นเช่นนี้POSIX แนะนำด้วย


หากคุณดูซอร์สโค้ดคุณจะสังเกตเห็นว่ามันใช้getoptเพื่อแยกวิเคราะห์ตัวเลือกบรรทัดคำสั่ง ที่นี่มีการจัดการพิเศษสำหรับโหมด 'ไม่ถูกต้อง' เช่น-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.  */

ยกตัวอย่างของคุณ:

  • chmod a-r file.txtจะเป็นการเรียกที่แข็งแกร่งที่สุด
  • chmod +r file.txt ใช้งานได้เนื่องจากอาร์กิวเมนต์แรกถูกตีความตำแหน่งเป็นโหมด
  • chmod -r file.txtยังใช้งานได้เพราะ-rถูกตีความว่าเป็นrตัวเลือกสั้น ๆและใส่กล่องพิเศษ
  • chmod -- -r file.txtถูกต้องและทำงานได้เนื่องจาก-rถูกตีความตำแหน่งเป็นโหมด ความแตกต่างนี้จากกรณีที่โดยไม่ต้อง--เพราะไม่ได้ตีความว่าเป็นตัวเลือก---r
  • chmod file.txt -rยังใช้งานได้เพราะ-rถูกตีความว่าเป็นrตัวเลือกสั้น ๆและใส่กล่องพิเศษ ตัวเลือกไม่ขึ้นอยู่กับตำแหน่ง เทคนิคนี้เป็นการดูหมิ่นที่ไม่มีเอกสารทางเทคนิค
  • chmod file.txt +rไม่ทำงานเนื่องจาก+rตัวถูกดำเนินการไม่ใช่ตัวเลือก ตัวถูกดำเนินการแรก ( file.txt) ถูกตีความว่าเป็นโหมด ... และล้มเหลวในการแยกวิเคราะห์

4
สิ่งนี้อาจมีผลที่น่าสนใจหากคุณมีชื่อไฟล์a+rwxและทำอะไรเช่นchmod * +rนั้นและa+rwxไฟล์จะเกิดขึ้นก่อนในการขยายแบบกลม
Jörg W Mittag

1
หรือไฟล์ชื่อ "-rf" ในกรณีของ "rm *"
Edeldil

@Edheldil ใช่คุณถูก ดูเหมือนว่าสิ่งที่ควรได้รับการแก้ไข (และข้อผิดพลาดเหมือนกับว่าข้อมูลไม่ถูกต้องอย่างถูกต้อง
TestyTentacleLinux

โปรดทราบว่าไวยากรณ์ OP ไม่ใช่ POSIX man7.org/linux/man-pages/man1/getopt.1.html#SCANNING_MODES
Steven Penny

@StevenPenny นั้นไม่เกี่ยวข้อง ประการแรก manpage เชื่อมโยงคือส่วนที่ 1 คือgetopt คำสั่งไม่ห้องสมุดประจำในส่วนที่ 3 ประการที่สองนั่นคือการอ้างอิงถึงoptstringคือรายการของตัวเลือกที่ยอมรับ (ในchmodแหล่งที่มาoptstringถูกตั้งค่าเป็น"Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::") ส่วน "โหมดการสแกน" ที่เชื่อมโยงนั้นไม่มีส่วนเกี่ยวข้องกับอาเรย์อาร์กิวเมนต์ argvที่มี args ที่ส่งผ่านเข้าไปในโปรแกรม
บ๊อบ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.