Prac06 ตอนที่ ๑ การเปลี่ยนทิศทาง input/output จงศึกษาคำสั่งของ Unix จากแฟ้ม Unix02.txt ให้เข้าใจ ทดลองใช้คำสั่งตามที่กำหนด อภิปรายผล และสรุบผลไปทีละตอน สร้างและเข้าสู่ไดเรกทอรี ~/886326/lab06 สร้างแฟ้ม yy.txt ซึ่งเป็น text file โดยให้มีข้อมูลภายในดังนี้ $ cat yy.txt This is yy.txt การสร้างแฟ้ม yy.txt จะเลือกใช้คำสั่ง echo หรือ cat ก็ได้ตามใจชอบ เพราะมีข้อมูลเพียงบรรทัดเดียว ไดเรกทอรีปัจจุบันในขณะนี้มีแฟ้มอยู่เพียงแฟ้มเดียว ตรวจสอบยืนยันด้วย $ ls -l -rw------- 1 jira staff 15 Nov 23 11:43 yy.txt หากใช้คำสั่ง $ cat yy.txt ... ... (1) ... ... ... ... ... ... ... คำถาม 1. ผลลัพธ์ที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? ผลที่ได้คือ This is yy.txt ซึ่งเป็น output ของคำสั่ง cat ที่ส่งออกทาง stdout -- ซึงในขณะนี้ต่ออยู่กับจอภาพ $ cat xx.txt ... ... (2) ... ... ... ... ... ... ... คำถาม 2. ผลลัพธ์ที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? ผลที่ได้คือ cat: xx.txt No such file or directory (ระบบแจ้งว่าไม่พบแฟ้ม xx.txt) ซึ่งเป็น error message ของคำสั่ง cat ที่ส่งออกทาง stderr -- ซึ่งขณะนี้ต่ออยู่กับจอภาพ ผลของการทดลองทั้งสองนี้จะเห็นได้ว่าโพรเซสของคำสั่ง cat เชื่อมต่อ stdout (file descriptor = 1) และ stderr (file descriptor = 2) เข้ากับจอภาพ ทดลองใช้คำสั่ง $ cat xx.txt yy.txt ... ... (3) ... ... ... ... ... ... ... (ก) ... ... ... ... ... ... ... (ข) คำถาม 3. ผลที่ตำแหน่ง (ก) เป็นอย่างไร? หมายความว่าอย่างไร? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... คำถาม 4. ผลลัพธ์ที่ตำแหน่ง (ข) คืออะไร ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... คำถาม 5. จากคำตอบของคำถามข้อ 3 และ 4 จะสรุปได้ว่าอย่างไร? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ทดลอง redirect ผลของคำสั่ง cat ไปยังแฟ้ม log ดังนี้ $ cat xx.txt yy.txt >log ... ... (4) ... ... ... ... ... ... ... คำถาม 6. ผลที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ตรวจสอบข้อมูลในแฟ้ม log ด้วยคำสั่ง $ cat log ... ... ... ... ... ... ... # This is yy.txt คำถาม 6. ผลที่ได้เป็นอย่างไร? หมายความว่าอย่างไร ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... สรุป $ คำสั่ง > ชื่อแฟ้ม เป็นการเปลี่ยนทิศทางของ stdout จากจอภาพเป็นแฟ้มที่กำหนด แต่ไม่สามารถเปลี่ยนทิศทางของ stderr ได้ การเปลี่ยนทิศทาง stderr ทดลองใช้คำสั่งต่อไปนี้ $ cat xx.txt yy.txt 1>log1 2>log2 ... ... (5) ... ... ... ... ... ... ... คำถาม 7. ผลที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ใช้คำสั่ง $ cat log1 ... ... ... ... ... ... ... (ค) $ cat log2 ... ... ... ... ... ... ... (ง) คำถาม 7. ผลที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? (ค) ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... (ง) ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ใช้คำสั่ง $ cat xx.txt yy.txt 1>log 2>&1 $ cat log ... ... ... ... ... ... ... คำถาม 8. ผลที่ได้เป็นอย่างไร? หมายความว่าอย่างไร? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ตอนที่ ๒ การประยุกต์การเปลี่ยนทิศทาง output และ error ในภาษา C ---------------------------------------------------------------------------- พิมพ์โปรแกรมภาษา C ดังนี้ $ cat -n hello.c 1 #include 2 3 int 4 main ( void ) 5 { 6 printf("Hello world.\n") // ไม่มี ; 7 8 return; // ไม่มี 0 9 } เมื่อทำการ compile ด้วยตัวแปลภาษา gcc ได้ error message ดังนี้ $ gcc -Wall hello.c hello.c: In function 'main': hello.c:8:6: error: expected ';' before 'return' hello.c:9:1: warning: control reaches end of non-void function [-Wreturn-type] 1. จงเพิ่มเติมคำสั่งให้ทำการเปลี่ยนทิศทางเฉพาะ stdout ของ gcc ไปยังแฟ้ม out ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 2. แฟ้ม out มีข้อมูลในแฟ้มหรือไม่? เพราะเหตุใด? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 3. จงเพิ่มเติมคำสั่งให้ทำการเปลี่ยนทิศทาง stdout และ stderr ของ gcc ไปรวมกันยังแฟ้ม out ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... พิมพ์โปรแกรมภาษา C ดังนี้ $ cat -n matrix.c 1 #include 2 3 int 4 main ( void ) 5 { 6 int a[3][4]; 7 int row, col; 8 9 printf("Enter matrix data :\n"); 10 for ( row = 0; row < 3; ++row ) { 11 for ( col = 0; col < 4; ++ col ) { 12 printf("A[%d][%d] = ", row, col ); 13 scanf("%d", &a[row][col]); 14 } 15 } 16 17 printf("\nInput matrix:\n"); 18 for ( row = 0; row < 3; ++row ) { 19 printf("| "); 20 for ( col = 0; col < 4; ++ col ) { 21 printf("%3d ", a[row][col]); 22 } 23 printf("|\n"); 24 } 25 26 return 0; 27 } เตรียมแฟ้มข้อมูล data ดังนี้ $ cat data 10 11 12 13 20 21 22 23 30 31 32 33 Compile โปรแกรม matrix.c และ run ดังนี้ $ gcc -Wall matrix.c $ a.out < data ผลที่ได้เป็นอย่างไร? การทำงานลักษณะนี้มีประโยชน์อย่างไร? และจากผลที่ได้ควรต้องมีการปรับปรุงโปรแกรมอย่างไร? ตอนที่ ๓ การป้องกัน > (redirection operator) การเขียนทับแฟ้มทีมีอยู่แล้ว ---------------------------------------------------------------------------------- ในวงการคอมพิวเตอร์คำว่า clobber เมื่อใช้กับแฟ้มหรือหน่วยความจำ หมายถึงการเขียนข้อมูลใหม่ทับข้อมูลเก่า และโดยทั่วไปมักจะเป็นการดำเนินการโดยไม่ตั้งใจ การเปลี่ยนทิศทาง output โดยใช้ > (redirection operator) ไปยังแฟ้ม หากชื่อแฟ้มที่กำหนดไม่มีอยู่ ระบบจะสร้างแฟ้มให้ จากนั้นจึงนำข้อมูลเขียนลงในแฟ้มนั้น ในกรณีที่มีแฟ้มที่กำหนดมีอยู่แล้ว ระบบจะทำการลบข้อมูลในแฟ้มทั้งหมด และนำข้อมูลเขียนลงในแฟ้มโดยไม่มีการถามผู้ใช้แต่อย่างใด เพื่อป้องกัน redirection operator เขียนข้อมูลทับแฟ้มที่มีอยู่แล้ว bash มี option "noclobber" ซึ่งสามารถเลือกใช้งานได้ โดยใช้คำสั่ง set ขอให้ทดลองตามตัวอย่างต่อไปนี้ $ echo "Hello world" >file.txt # เปลี่ยนทิศทาง output ไปยังแฟ้ม file.txt $ cat file.txt Hello world $ echo "Overwrite first greeting" >file.txt # ข้อมูลเก่าจะถูกข้อมูลใหม่เขียนทับ $ cat file.txt Overwrite first greeting $ set -o noclobber # เรียกใช้ (-o) option ที่ป้องกันการเขียนทับ (noclobber) $ echo "Overwrite again" >file.txt # ทดลองเขียนทับ -bash: file.txt: cannot overwrite existing file # error $ echo "Overwrite again" >|file.txt # ต้องการเขียนทับจริงทำได้โดยใช้ >| $ cat file.txt Overwrite again $ set +o noclobber # ยกเลิก (+o) option ที่ป้องการกันการเขียนทับ ตอนที่ ๔ Unix pipeline -------------------------- ๑. จงอธิบายการทำงานของคำสั่งต่อไปนี้ $ who | cut -c1-8 | sort > attend.txt คำสั่ง cut ---------- cut - ตัดเฉพาะส่วนที่กำหนดจากแต่ละบรรทัดในแฟ้ม รูปแบบการใช้งาน cut [-option] [<ชื่อแฟ้ม>] option ที่ใช้งาน -c กำหนดตำแหน่งตัวอักษรของข้อมูลที่ต้องการตัด เช่น -c1-8 ตัดข้อมูลเฉพาะจากอักษรตัวที่ 1 ถึงตัวที่ 8 ๒. จงเขียน Unix pipeline เพื่อแสดงรายละเอียดของแฟ้มที่มีขนาดใหญ่ที่สุด 5 แฟ้มแรกใน /usr/bin คำแนะนำ -- sort, head