Note02.txt -- ข้อสังเกตจาก prac02.txt ตอนที่ ๑ การแสดงผลและความหมายของคำสั่ง ls ----------------------------------------------------- ls -l ---- + ขนาดของแฟ้มเป็นไบต์ - ขนาดของไดเรกทอรีสมนัยกับขนาดของ block | + วันเวลาที่มีการดำเนินการกับแฟ้มครั้งล่าสุด | | + ชื่อแฟ้ม | | | drwxr-x--- 2 jira staff 4096 Jan 16 08:23 H | | | | | | | + ชื่อกลุ่ม (group) ที่เจ้าของสังกัด | | + ชื่อเจ้าของ (owner) | | + จำนวน link (รายละเอียดจะกล่างถึงต่อไป) + ชนิดของแฟ้ม และสิทธิการใช้งาน (permission) d ... ... ... | อักษรตัวแรก (ซ้ายมือสุด) - ชนิดของแฟ้ม - แฟ้มธรรมดา d ไดเรกทอรี l symbolic link p named pipe หรือ fifo - ช่องทางสื่อสารข้อมูลระหว่างโพรเซส s socket - ช่องทางสื่อสารข้อมูลผ่านเครือข่าย c character special file - แฟ้มแทนอุปกรณ์ที่มีการส่งผ่านข้อมูลครั้งไบต์ เช่น แป้นพิมพ์ b block special file - แฟ้มแทนอุปกรณ์ที่มีการส่งผ่านข้อมูลครั้ง block เช่น hard disk drive ... rwxr-x--- | สิทธิในการใช้งานแฟมแบ่งเป็น 3 ชุด ชุดละ 3 ตัว rwx สิทธิของเจ้าของ (owner) r-x สิทธิของกลุ่ม (group) --- สิทธิของผู้ใช้ทั่วไป (other) ls -F ---- ls -F ใช้จำแนกชนิดของแฟ้ม โดยใช้อักขระต่อไปนี้ตามหลังชื่อแฟ้ม / directory * executable @ symbolic link = socket | fifo แฟ้มธรรมดาไม่มีอักขระใดตามหลัง ตัวอย่างเช่น $ ls -F H/ star.c a.out* การเลือกใช้ option -l และ -F ตอนที่ ๒ จำนวน Utilities ของระบบปฏิบัติการ ------------------------------------------------- วิธีการที่ง่ายที่สุดคือการทำ pipeline: การนำ output ของคำสั่ง ls เป็นข้อมูล input ของคำสั่ง wc โดยต้องดำเนินการทีละไดเรกทอรี เก็บผลลัพธ์ไว้ และนำมาคำนวณโดยใช้ bc --> รู้จักการทำ pipeline เบื้องต้น และการเลือก option ให้เหมาะกับงาน โดยปกติเมื่อโปรแกรม ls ทำงานจะแสดงผลออกทางอุปกรณ์แสดงผลมาตรฐาน (standard output หรือนิยมเรียกตามการใช้งาน ภาษา C ว่า stdout) ซึ่งโดยปริยายได้แก่ จอภาพ นอกจากนี้ผู้ใช้ยังสามารถกำหนดให้ส่งข้อมูลลงสู่ pipe ซึ่งเป็นช่องทางสื่อสารข้อมูล ระหว่างโพรเซสได้ และโดยปกติโปรแกรม wc รับข้อมูลเข้าจากแฟ้มที่ผู้ใช้กำหนด หรือรับข้อมูลโดยตรงจากแป้นพิมพ์ซึ่งเป็นอุปกรณ์รับ ข้อมูลมาตรฐาน (standard input หรือนิยมเรียกตามการใช้งานภาษา C ว่า stdin) นอกจากนี้ผู้ใช้ยังสามารถกำหนดให้รับข้อมูลที่ส่งมา จาก pipe ได้ คำสั่ง ls | wc -l เป็นการกำหนดให้ ls ส่งผลลัพธ์ซึ่งได้แก่รายชื่อแฟ้มในไดเรกทอรีปัจจุบันลงสู่ pipe และกำหนดให้ wc อ่านข้อมูล จาก pipe มาทำการนับจำนวนบรรทัด ซึ่งได้แก่จำนวนบรรทัดของรายชื่อแฟ้ม --> จำนวนแฟ้มในไดเรกทอรีปัจจุบัน --> รู้จักเครื่องคิดเลขของระบบปฏิบัติการ Unix $ ls /bin | wc -l # จำนวน Utilities ใน /bin ซึ่งเป็น Utilities ที่จำเป็นต้องใช้งานในการ boot ระบบ 149 # หรือเป็น Utilities ที่จำเป็นสำหรับการ boot ใน single-user mode $ ls /sbin | wc -l # จำนวน Utilities ใน /sbin ซึ่งเป็น Utilities ที่จำเป็นในการ boot ระบบ แต่ต้องการ 173 # สิทธิในระดับ superuser ในการเรียกใช้งาน $ ls /usr/bin | wc -l # จำนวน Utilities ใน /usr/bin ซึ่งเป็น Utilities สำหรับผู้ใช้ทุกคนในระบบ 865 $ ls /usr/sbin | wc -l # จำนวน Utilities ใน /usr/sbin ซึ่งเป็น Utilities สำหรับ superuser ผู้ใช้อื่นอาจเรียก 227 # ใช้งานได้ แต่อาจใช้งานได้เพียงบางอย่าง จากนั้นนำผลลัพธ์ที่ได้ในแต่ละคำสั่งมาป้อนให้กับโปรแกรม basic calculator ดังนี้ $ bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 149+173+865+227 1414 quit # เลิกการทำงานของโปรแกรม bc การทำงานแบบนี้ยังไม่เป็นอัตโนมัติ ควรต้องปรับปรุงให้ดีขึ้น หากอ่าน Online manual page ของ ls จะเห็นว่าสามารถกำหนดไดเรกทอรี ได้หลายไดเรกทอรี หากกำหนดให้ ls แสดงผลไดเรกทอรีทั้งหมดพร้อมกัน และทำการส่งผลลัพธ์ผ่าน pipe ไปยังคำสั่ง word count น่า จะได้ผลเช่นเดียวกัน ดังนั้นจึงน่าจะใช้คำสั่งต่อไปนี้ได้ $ ls /bin /sbin /usr/bin /usr/sbin | wc -l อย่างไรก็ดีคำสั่งนี้ให้ผลลัพธ์เป็น 1421 ซึ่งเป็นผลลัพธ์ที่มีค่ามากกว่าความเป็นจริง -- จึงไม่สามารถใช้วิธีการนี้ได้ คำถาม ------- ทำอย่างไรจึงจะรู้ได้ว่าค่าที่มากกว่าความเป็นจริง = 7 มาจากไหน? จะออกแบบวิธีการทดลองอย่างไร? โจทย์ข้อนี้ต้องการให้ผู้เรียนคิด เพื่อเป็นการนำไปสู่การเรียนการสอนเรื่อง Command substitution การทำ Command Substitution ----------------------------------- Command substitution เป็นการนำ "ผลลัพธ์ (output)" ของคำสั่งหรือกลุ่มของคำสั่งมาแทนที่คำสั่งนั้น โดยกำกับด้วยเครื่องหมาย backquote (`) เช่น $ echo `ls /bin | wc -l` เริ่มทำงานตามคำสั่งที่กำกับด้วยเครื่องหมาย backquote ก่อนคือ `ls /bin | wc -l` ซึ่งเป็นการกำหนดให้ shell ทำการแสดงรายชื่อแฟ้ม ในไดเรกทอรี /bin และนำผลลัพธ์ที่ได้เป็น input ของโปรแกรม wc ซึ่งกำหนดให้นับเฉพาะจำนวนบรรทัด และส่งจำนวนบรรทัดที่นับได้ ออกทาง standard output ซึ่งคำสั่งนี้ให้ผลลัพธ์เป็น 149 ผลลัพธ์นี้จะถูกนำไปแทนคำสั่งใน backquote เป็น $ echo 149 จึงได้ผลลัพธ์เป็น 149 เราจะนำ Command substitution มาใช้ในการนับจำนวน Utilities ขอให้ศึกษาตัวอย่างต่อไปนี้ หากใช้คำสั่ง $ echo `ls /bin | wc -l` + `ls /sbin | wc -l` + `ls /usr/bin | wc -l` + `ls /usr/sbin | wc -l` จะได้ผลลัพธ์เป็น 149 + 173 + 865 + 227 ซึ่ง output ของคำสั่ง echo เป็นนิพจน์คณิตศาสตร์ที่สามารถนำไปใช้เป็น input ของ bc ได้ -- ทำ pipelining $ echo `ls /bin | wc -l` + `ls /sbin | wc -l` + `ls /usr/bin | wc -l` + `ls /usr/sbin | wc -l` | bc 1414 ตอนที่ ๓ Algorithm สำหรับ Automatic filename completion -------------------------------------------------------------------- ก่อนจะลงมือคิดขั้นตอนวิธี กำหนดรายละเอียด (Specification) การทำงานของโปรแกรมก่อน - ยังไม่มีการป้อนอักขระใดเลย และกดแป้น Tab --> ไมเปลี่ยนแปลง - มีการป้อนตัวอักษรแล้ว และกดแป้น Tab ถ้า มีชื่อแฟ้มที่ขึ้นต้นด้วยกลุ่มอักษรนั้นเพียงแฟ้มเดียว --> แสดงชื่อแฟ้มนั้น เลิกการทำงาน ถ้า มีชื่อแฟ้มที่ขึ้นต้นด้วยกลุ่มอักษรนั้นหลายแฟ้ม --> ไม่เปลี่ยนแปลง ถ้า กดแป้น Tab --> แสดงชื่อแฟ้มที่ขึ้นต้นด้วยกลุ่มนั่นทั้งหมด แสดงชื่อที่ผู้ใช้ป้อนไว้เดิม ถ้า กดแป้นตัวอักษรอื่น --> เป็นการเพิ่มชื่อแฟ้ม ย้อนกลับไปทำงานที่ต้น block นี้ใหม่ Algorithm ----------- กำหนด flag การค้นให้มีสถานะเป็น "ไม่พบ" repeat ผู้ใช้ป้อนอักขระซึ่งเป็น "ส่วนหนึ่ง" ของชื่อแฟ้ม ผู้ใช้กด อ่านรายชื่อแฟ้มในไดเรกทอรีปัจจุบัน -- ใช้เป็น search string ชื่อแฟ้ม (บางส่วน) ของผู้ใช้ -- ใช้เป็น search key { ค้นรายชื่อแฟ้มที่มีสายอักขระเริ่มต้นตรงกับชื่อของผู้ใข้ - string matching algorithm , if พบ then if พบชื่อแฟ้มเพียงชื่อเดียว then แสดงชื่อแฟ้มที่พบ กำหนด flag การค้นให้มีสถานะเป็น "พบ" else { พบชื่อแฟ้มตรงกันหลายแฟ้ม } if ผู้ใช้กด แสดงรายชื่อแฟ้มที่ตรงกันทั้งหมด end {if} end {if} end {if} until flag การค้นมีสถานะเป็นพบ Algorithm นี้ยังไม่สมบูรณ์ ถ้าไม่พบแฟ้มที่จรงกันเลย และผู้ใช้ต้องป้อนชื่อแฟ้มจนจบแล้วกด ควรต้องทำอย่างไร? ตอนที่ ๔ การสร้างโครงสร้างไดเรกทอรีในปฏิบัติการ Prac02 ---------------------------------------------------------------- โครงสร้างไดเรกทอรีที่กำหนด 886326 | +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... | | +---------+-----------+-+-------+---------+ +----+----+ | | | | | | | A B C D E F G การสร้างไดเรกทอรี --------------------- การสร้างไดเรกทอรีใช้คำสั่ง mkdir (make directory) และไดเรกทอรีที่สร้างขึ้น จะอยู่ในไดเรกทอรีปัจจุบันเสมอ กล่าวเป็นภาษาทาง วิชาการว่าไดเรกทอรีที่สร้างขึ้นเป็นไดเรกทอรีย่อย หรือ subdirectory ของไดเรกทอรีปัจจุบันเสมอ -- ในแผนภาพที่ใช้งานต่อไป จะใช้สัญลักษณ์ดอกจัน (*) แทนไดเรกทอรีปัจจุบัน กำหนดให้ไดเรกทอรีปัจจุบัน (working directory หรือ current directory) เป็น home directory (~) ของผู้ใช้แต่ละคน เมื่อใช้คำสั่ง pwd จะได้ผลเช่น $ pwd /home/staff/jira -- Home directory ของผู้ใช้ jira เมื่ออยู่ใน Home directory (ซึ่งแทนด้วย ~) แล้ว ทำการสร้างไดเรกทอรี 886326 โดยใช้คำสั่ง $ mkdir 886326 เมื่อสร้างไดเรกทอรีแล้ว ควรตรวจสอบด้วยคำสั่ง ls -l เช่น $ ls -l total 4 drwx------ 2 jira staff 4096 Jan 16 11:20 886326 หรือ ls -F $ ls -F 886326/ จะเห็นชื่อไดเรกทอรี 886326 แสดงด้วยแผนภาพได้ดังนี้ Home directory (~) | * ----------+------------+---------------------+------- | 886326 เมื่อต้องการสร้างไดเรกทอรี H และไดเรกทอรี K ซึ่งเป็นไดเรกทอรีย่อยของ 886326 ต้องเข้าสู่ 886326 ด้วยคำสั่ง $ cd 886326 เมื่อเปลี่ยนไดเรกทอรีแล้ว ควรได้ตรวจสอบด้วยคำสั่ง pwd (print working directory) $ pwd /home/staff/jira/886326 แสดงว่าไดเรกทอรีปัจจุบันเปลี่ยนจาก home เป็น 886326 เรียบร้อยแล้ว Home directory (~) | ----------+------------+---------------------+------- | 886326 | * Tip: ทุกครั้งที่มีการสร้างแฟ้มและไดเรกทอรี ควรตรวจสอบด้วยคำสั่ง ls และทุกครั้งที่มีการเปลี่ยนไดเรกทอรี ควรตรวจสอบด้วยคำสั่ง pwd เสมอ เมื่ออยู่ใน 886326 แล้ว จึงจะสามารถสร้างไดเรกทอรี H และ K ได้ และสร้างแฟ้ม xx.txt, xy.txt, xz.txt และ yy.txt ได้ ทำการสร้างแฟ้ม xx.txt, xy.txt, xz.txt และ yy.txt ตามที่โจทย์กำหนด $ ls -F xx.txt xy.txt xz.txt yy.txt | 886326 | * +-----------------+-----------------+------------------+-----------+---------+----- | | | xx.txt yy.txt ... ... จากนั้นจึงทำการสร้างไดเรกทอรี H และ K โดยใช้คำสั่ง $ mkdir H K ตรวจสอบด้วยคำสั่ง ls -F $ ls -F H/ K/ xx.txt xy.txt xz.txt yy.txt | 886326 | * +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... ต่อไปจะทำการสร้างไดเรกทอรี A, B, C, D, และ E ซึ่งเป็นไดเรกทอรีย่อยของ H ต้องเข้าสู่ไดเรกทอรี H ก่อน ด้วยคำสั่ง $ cd H ตรวจสอบไดเรกทอรีปัจจุบันด้วย pwd | 886326 | +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... |* (5). เมื่ออยู่ในไดเรกทอรี H แล้ว ทำการสร้างไดเรกทอรี A, B, C, D, และ E ด้วยคำสั่ง $ mkdir A B C D E ตรวจสอบด้วย ls -l หรือ ls -F | 886326 | +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... |* +---------+-----------+-+-------+---------+ | | | | | A B C D E ต่อไปจึงทำการสร้าง F และ G ให้เป็นไดเรกทอรีย่อยของ K ซึ่งจะสร้างได้ก็ต่อเมื่ออยู่ในไดเรกทอรี K แล้ว เปลี่ยนไดเรกทอรีปัจจุบันจาก H เป็น K -- จะเห็นว่า H และ K เป็นไดเรกทอรีที่อยู่ในระดับเดียวกัน จะเข้าสู่ไดเรกทอรี K ได้ ต้องเลื่อนขึ้นไปหนึ่งระดับ คือขึ้นไปอยู่ใน 886326 ซึ่ง เป็น parent directory (แทนด้วย ..) เขียนเป็นคำสั่งได้ดังนี้ $ cd .. ... ... ... (1) ตรวจสอบด้วย pwd | 886326 |* +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... | +---------+-----------+-+-------+---------+ | | | | | A B C D E เมื่ออยู่ใน 886326 แล้ว จึงเข้าสู่ไดเรกทอรี K ด้วยคำสั่ง $ cd K ... ... ... (2) ตรวจสอบด้วย pwd | 886326 | +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... | |* +---------+-----------+-+-------+---------+ | | | | | A B C D E หมายเหตุ คำสั่ง (1) และ (2) คือ $ cd .. ... ... ... (1) $ cd K ... ... ... (2) สามารถรวมเป็นคำสั่งเดียวคือ $ cd ../K เลื่อนขึ้นไปหนึ่งระดับแล้วเข้าสู่ไดเรกทอรี K เมื่ออยู่ในไดเรกทอรี K แล้ว จึงทำการสร้างไดเรกทอรี F และ G ด้วยคำสั่ง $ mkdir F G ตรวจสอบด้วย ls -l หรือ ls -F | 886326 | +-----------------+-----------------+------------------+-----------+---------+----- | | | | | H K xx.txt yy.txt ... ... | |* +---------+-----------+-+-------+---------+ +----+----+ | | | | | | | A B C D E F G จะได้โครงสร้างไดเรกทอรีตามที่โจทย์กำหนดสำหรับใช้เป็นแบบฝึกหัดในการคัดลอกและเปลี่ยนสิทธิแฟ้ม ตอนที่ ๕ - คำสั่ง cp และเส้นทาง ------------------------------------ คำสั่ง cp มีหลายรูปแบบ รูปแบบที่ง่ายที่สุดคือ cp source destination # cp ต้นทาง ปลายทาง หรือ cp ต้นฉบับ สำเนา การดำเนินการคัดลอกแฟ้ม ผู้ใช้ต้องรู้ว่า (1). พื้นที่ทำงานปัจจุบัน หรือไดเรกทอรีปัจจุบันอยู่ที่ไหน? (2). แฟ้มต้นฉบับอยู่ที่ไหน?, และ (3). สำเนาที่ได้จะเก็บไว้ที่ไหน? ตัวอย่างการคัดลอกแฟ้ม -------------------------- แบบฝึกหัดข้อ 1. ทำการคัดลอกแฟ้ม xx.txt ไปยังไดเรกทอรี A, C, D, F, และ H การคัดลอกแฟ้ม xx.txt ไปยังไดเรกทอรีต่างๆ คำสั่ง cp ทำได้ครั้งละแฟ้มเดียว บรรทัดคำสั่งของ cp ไม่ตายตัว ขึ้นอยู่กับไดเรกทอรี ปัจจุบันของผู้ใช้ ดังตัวอย่างต่อไปนี้ ก. ไดเรกทอรีปัจจุบันของผู้ใช้อยู่ที่ 886326 ต้องคัดลอกแฟ้ม xx.txt ไปยังไดเรกทอรี A แฟ้มต้นฉบับ xx.txt อยู่ในไดเรกทอรี 886326 ผู้ใช้จึงระบุชื่อ xx.txt ได้โดยตรง ปลายทางคือไดเรกทอรี A โดยแฟ้มสำเนามีชื่อเป็น xx.txt เช่นเดียวกับแฟ้มต้นฉบับ "เส้นทาง" จากไดเรกทอรีปัจจุบัน (886326) ไปยังไดเรกทอรี A คือ ไดเรกทอรีปัจจุบัน (แทนด้วย .) --> ไดเรกทอรี H --> ไดเรกทอรี A ต้นทาง ./xx.txt หรือ xx.txt ปลายทาง ./H/A/ หรือ ./H/A หรือ H/A บรรทัดคำสั่ง cp <ต้นทาง> <ปลายทาง> cp ./xx.txt ./H/A/ ข. ไดเรกทอรีปัจจุบันของผู้ใช้อยู่ที่ K ต้องคัดลอกแฟ้ม xx.txt ไปยังไดเรกทอรี A ต้นทาง แฟ้ม xx.txt อยู่ใน parent directory (แทนด้วย ..) ซึ่งอยู่เหนือขึ้นไปหนึ่งระดับ -- ../xx.txt ปลายทาง ไดเรกทอรี A เป็นไดเรกทอรีย่อยของ H ซึ่งอยู่ในระดับเดียวกับ K จาก K จะไปยัง H ได้ ต้องเลื่อนขึ้นหนึ่งระดับสู่ parent directory (..) จากนั้นจึงลงไปในไดเรกทอรี H แล้วลงไปในไดเรกทอรี A ปลายทางจึงเป็น ../H/A บรรทัดคำสั่ง cp ../xx.txt ../H/A เมื่อคัดลอกสามารถใช้ำสัง ls ดูผลได้ดังนี้ $ ls -l ../H/A -- ขอดูรายชื่อแฟ้มทั้งหมดในไดเรกทอรี A ค. ไดเรกทอรีปัจจุบันของผู้ใช้อยู่ที่ A ต้องคัดลอกแฟ้ม xx.txt ซึ่งอยู่ในไดเรกทอรี 886326 มายังไดเรกทอรี A ต้นทาง จากไดเรกทอรีปัจจุบัน ขึ้นไปยังไดเรกทอรี H (ซึ่งเป็น parent directory ของ A) และขึ้นต่อไปยังไดเรกทอรี 886326 ซึ่งเป็น parent directory ของ H ../../xx.txt ปลายทาง ไดเรกทอรีปัจจุบัน (แทนด้วย .) บรรทัดคำสั่ง cp ../../xx.txt . เมื่อทำแบบฝึกหัดเสร็จไปครั้งหนึ่งแล้ว หากมีความประสงค์จะทำใหม่อีกครั้งหนึ่งเพื่อฝึกความชำนาญ ต้องลบโครงสร้างไดเรกทอรีทั้งหมด ก่อน แต่เนื่องจากคำสั่ง rmdir ใช้ลบได้เฉพาะไดเรกทอรีที่ว่าง (ไม่มีแฟ้ม) ดังนั้นหากในไดเรกทอรียังมีแฟ้มอยู่ ต้องลบแฟ้มในไดเรกทอรี ให้หมดก่อน ซึ่งแฟ้มที่ผู้ใช้จะทำการลบต้องมีสิทธิ w ในแฟ้มนั้น หากไม่มีระบบจะสอยถามเพื่อให้ผู้ใช้ยืนยัน เช่น $ ls -l -r-------- 1 jira staff 110 Jan 16 11:48 tmp.txt $ rm tmp.txt rm: remove write-protected regular file tmp.txt? ระบบจะสอบถามว่าต้องการลบแฟ้ม tmp.txt ซึ่งป้องกันการเขียนทับ (write-protected) หรือไม่? หากผู้ใช้กดแป้น y จะยืนยันการลบแฟ้ม หากกดแป้น n จะไม่มีการลบแฟ้ม เมื่อลบแฟ้ม (คำสั่ง rm) ในไดเรกทอรีนั้นหมดแล้ว จึงจะทำการลบไดเรกทอรี (คำสั่ง rmdir) นั้นได้ โดยผู้ใช้ต้องอยู่เหนือไดเรกทอรีนั้น ตอนที่ ๖ - สิทธิในการใช้งานแฟ้ม ------------------------------------ แฟ้มที่อยู่ในไดเรกทอรี F และ G เจ้าของมีสิทธิเฉพาะ read กลุ่มและผู้ใช้ไม่มีสิทธิใดเลย หรือ - r-- --- --- ประโยชน์ - ใช้เพื่อป้องกันการลบโดยอุบัติเหตุซึ่งไม่น่าจะใช้ได้กับนิสิต เพราะไม่สนใจและไม่ชอบอ่าน error message ความเข้าใจผิดในเรื่องการเปลี่ยนสิทธิในการใช้งาน ------------------------------------------------------ แบบฝึกหัดข้อ 3. แฟ้มที่อยู่ในไดเรกทอรี H และ K ให้เจ้าของและกลุ่มมีสิทธิ read และ write ผู้ใช้อื่นในระบบมีสิทธิเฉพาะ read ปัญหา - นิสิตคิดว่าการกำหนดให้แฟ้มหลายแฟ้มในไดเรกทอรีมีสิทธิแบบเดียวกัน สามารถทำได้โดยการ chmod ตัวไดเรกทอรี เช่น $ chmod 0665 H "คาดว่า" คำสั่งนี้จะทำให้แฟ้มทั้งหมดในไดเรกทอรี H คือ xx.txt มี permission เป็น -rw-rw-r-- "ความเป็นจริง" คำสั่งนี้ไม่มีผลใดๆ กับแฟ้ม xx.txt เลย แต่เป็นคำสั่งที่ใช้กำหนดสิทธิไดเรกทอรี H ให้มี permission เป็น -rw-rw-r-- $ chmod 665 H $ ls -l total 4 drw-rw-r-x 2 jira staff 4096 Jan 16 08:23 H เมื่อต้องการเข้าสู่ไดเรกทอรี H โดยใช้คำสั่ง $ cd H -bash: cd: H: Permission denied หมายความว่า bash ไม่สามารถทำงานตามคำสั่ง cd ได้เนื่องจากไม่มีสิทธิในการทำงานใน H หรือ ผู้ใช้ไม่มีสิทธิเข้าสู่ไดเรกทอรี สรุป (ถอนสิทธิ x ออกจากไดเรกทอรี H) and (เข้าสู่ไดเรกทอรี H ไม่ได้) ----> ... ... ... ... ... ... ... ... เรียนรู้อย่างหนึ่งว่า สิทธิ x ของไดเรกทอรี ใช้ในการเปลี่ยน (เข้าสู่) ไดเรกทอรีนั้น เมื่อเข้าไดเรกทอรีไม่ได้ ก็ขอดูรายชื่อแฟ้มในไดเรก ทอรีนั้นไม่ได้ หรือไม่มีสิทธิในการค้นแฟ้มในไดเรกทอรี สิทธิการใช้งานของไดเรกทอรีและแฟ้มไม่เหมือนกัน ------------------------------------------------------- File access permission -------------------------- การเข้าถึงแฟ้ม (access) ขึ้นอยู่กับสิทธิการใช้แฟ้มของผู้ดำเนินการ - การอ่านข้อมูลในแฟ้ม ต้องมีสิทธิในการ read (r) - การเปลี่ยนแปลงข้อมูลในแฟ้ม ต้องมีสิทธิ write (w) - การกำหนดให้แฟ้มโปรแกรมไม่ว่าจะเป็น executable file หรือ script ทำงาน ต้องมีสิทธิ execute (x) Directory access permission -------------------------------- เนื่องจากไดเรกทอรีมีความแตกต่างจจากแฟ้มธรรมดา "สิทธื" ในการเข้าถึงไดเรกทอรีจึงมีความแตกต่างออกไปจากแฟ้มธรรมดา - การอ่านรายชื่อแฟ้มในไดเรกทอรี ต้องมีสิทธิ read (r) ไม่ว่าจะมีสิทธิ read สำหรับแฟ้มเหล่านั้นหรือไม่ อย่างไรก็ดีสิทธิในการ read แสดงได้เฉพาะชื่อแฟ้มเท่านั้น (ใช้คำสั่ง ls ได้) แต่ไม่สามารถแสดงคุณสมบัติของแฟ้มได้ (ไม่สามารถ ใช้คำสั่ง ls -l ได้) - การสร้างแฟ้มใหม่, การลบแฟ้มที่มีอยู่ หรือ การเปลี่ยนชื่อแฟ้ม ต้องมีสิทธิ write (w) ในไดเรกทอรีนั้น ไม่ว่าจะมีสิทธิ write สำหรับ แฟ้มที่จะลบหรือเปลี่ยนชื่อหรือไม่ก็ตาม - สืทธิในการ execute (x) ไดเรกทอรี มีไว้สำหรับให้ผู้ใช้สามารถอ่านคุณสมบัติของแฟ้มในไดเรกทอรีนั้นได้ และสามารเปลี่ยนพื้นที่ ทำงานเข้าไปในไดเรกทอรีนั้นได้ หรือกล่าวในทางวิชาการคือสิทธิในการ execute ของไดเรกทอรี เป็นสิทธิที่ทำให้สามารถเข้าถึง index node (i-node) ของแฟ้มที่อยู่ในไดเรกทอรีนั้นได้ ตอนที่ ๗ ของแถม -------------------- ๑. ls -F กับ execuatable file เมื่อกำหนดคำสั่ง umask 0700 ไว้ในแฟ้ม .bash_profile จะกำหนดให้แฟ้มที่ผู้ใช้สร้างมีสิทธิการใช้งาน (Permission) สำหรับเจ้าของเป็น rwx------ ซึ่งสิทธิดังกล่าวนี้ shell จะกำหนดให้เหมาะสมกับประเภทของแฟ้ม กล่าวคือแฟ้มธรรมดากำหนดสิทธิเป็น -rw------- ส่วนแฟ้มที่เป็น executable จึงจะกำหนดให้เป็น -rwx------ เช่น $ ls -l -rwx------ 1 jira staff 8514 Jan 14 13:26 a.out binary executable file -rw------- 1 jira staff 223 Jan 14 13:26 star.c C source code $ ls -F a.out* star.c hello.c เป็นแฟ้มธรรมดา, a.out เป็น executable $ a.out executable สามารถ run ได้ * ** *** **** ***** $ chmod 600 a.out เปลี่ยนสิทธิ a.out เป็น -rw------- $ ls -l total 16 -rw------- 1 jira staff 8514 Jan 14 13:56 a.out a.out เปลี่ยนเป็นแฟ้มธรรมดา -rw------- 1 jira staff 222 Jan 14 13:56 hello.c $ ls -F a.out hello.c $ a.out ไม่สามารถเรียกให้ทำงานได้อีก -bash: ./a.out: Permission denied ๒. มีนิสิตถามว่าถ้าอยากให้ wc แสดงจำนวนไบต์ จะทำอย่างไร คำตอบ : man wc เมื่อถูกบังคับให้อ่าน ไม่นานก็สามารถบอกได้ว่าใช้ option -c (character) --> ภายใต้สถานการณ์บังคับ นิสิตก็สามารถอ่าน online manual page ภาษาอังกฤษ และสามารถหาคำตอบที่ต้องการได้