Note06 เก็บตกจากปฏิบัติการเรื่อง i/o redirection ----------------------------------- คำชี้แจง: 1. กำหนดการใช้คำภาษาไทยดังนี้ :- ผลลัพธ์ ใช้แทน output, และ ข่าวสารความผิดพลาด ใช้แทน error message 2. กำหนดให้ในไดเรกทอรีปัจจุบัน (.) มีแฟ้ม yy.txt แต่ไม่มีแฟ้ม xx.txt 3. คำสั่ง cat ตัดมาจากคำว่า concatenation แปลว่า การเชื่อมเข้าด้วยกัน หรือ การต่อกัน จากการทดลอง คำสั่ง cat มีการแสดงผลตามลำดับดังนี้ $ cat yy.txt # แสดงข้อมูลในแฟ้ม yy.txt This is yy.txt # ออกทาง stdout --> จอภาพ $ cat xx.txt # ไม่มีแฟ้มหรือไดเรกทอรีชื่อ xx.txt cat: xx.txt: No such file or directory # แสดงคำเตือน (ความผิดพลาด) ทาง stderr --> จอภาพ $ cat yy.txt xx.txt # โดยปริยาย stdout และ stderr เชื่อมเข้าหากัน และต่อกับจอภาพ This is yy.txt # แสดงผลผลลัพธ์ทางทางจอภาพ และ cat: xx.txt: No such file or directory # แสดงข่าวสารความผิดพลาดทางจอภาพ (1). บรรทัดคำสั่ง $ cat yy.txt xx.txt 1> log1 2> log2 กำหนดให้มีการเปลี่ยนทิศทางของผลลัพธ์มาตรฐาน (stdout: file descriptor = 1) ไปยังแฟ้มชื่อ log1 และกำหนดให้มีการเปลี่ยนทิศทางของข่าวสารความผิดพลาด (stderr: file descriptor = 2) ไปยังแฟ้ม log2 (2). บรรทัดคำสั่ง $ cat yy.txt xx.txt 1> log 2> log กำหนดให้มีการเปลี่ยนทิศทางของ stdout ไปยังแฟ้ม log และเปลี่ยนทิศทางของ stderr ไปยังแฟ้ม log เช่นเดียวกัน เมื่อคำสั่ง cat ทำงาน จะเริ่มทำงานกับแฟ้ม yy.txt ก่อน โดยเขียนข้อมูลในแฟ้ม yy.txt ลงในแฟ้ม log เมื่อแล้วเสร็จจะดำเนินการต่อกับแฟ้ม xx.txt ซึ่งไม่สามารถทำงานได้ เพราะแฟ้มนี้ไม่มีอยู่จริง จึงส่งข่าวสารความผิดพลาดลงในแฟ้ม log โดยเริ่มจากต้นแฟ้ม (> จะเขียนข้อมูลโดยเริ่มจากต้นแฟ้มเสมอ) จึงเป็นเขียนทับผลลัพธ์เดิมที่มีอยู่ในแฟ้ม เมื่อเขียนเสร็จ จะทำการปิดแฟ้ม ดังนั้น → ข้อมูลในแฟ้ม log จึงมีเฉพาะข่าวสารความผิดพลาด ในทำนองเดียวกัน หากสลับที่ชื่อแฟ้มในคำสั่งเป็น $ cat xx.txt yy.txt 1> log 2> log → ข้อมูลในแฟ้ม log จะมีเฉพาะผลลัพธ์ เพื่อป้องกันการเขียนทับโดยไม่เจตนา ผู้ใช้สามารถกำหนดให้คำสั่งที่จะมีการเขียนทับหยุดการทำงาน และแสดงคำเตือนได้ โดยใช้คำสั่ง set -o noclobber (clobber - กระหน่ำตีซ้ำ, noclobber - ไม่ตีซ้ำ) $ set -o noclobber $ cat yy.txt xx.txt 1>log 2>log -bash: log: cannot overwrite existing file # bash ไม่สามารถเขียนข้อมูลทับแฟ้มที่มีอยู่แล้วได้ และแฟ้ม log ที่มีการสร้างขึ้นจะเป็นแฟ้มว่าง (มีขนาดเป็น 0 ไบต์) (3). บรรทัดคำสั่ง $ cat yy.txt xx.txt 1> log 2>&1 กำหนดให้มีการเปลี่ยนทิศทางของ stdout ไปยังแฟ้ม log และเปลี่ยนทิศทางของ stderr ไปยังที่เดียวกับ stdout เป็นการ "ควบรวม" stdout และ stderr ให้ไปยังแฟ้มเดียวกัน เป็นการเขียนข้อมูลลงในแฟ้ม log ต่อกัน ข้อมูลไม่ทับกัน → ข้อมูลในแฟ้ม log จึงมีทั้งผลลัพธ์ และ ข่าวสารความผิดพลาด การวางตำแหน่งของ redirection operator จะอ้างอิง stdout หรือ stderr ก่อนก็ได้ ดังนั้นคำสั่ง $ cat yy.txt xx.txt 1> log 2>&1 จึงสมนัยกับ $ cat yy.txt xx.txt 2> log 1>&2 แต่ต้องอ้างชื่อแฟ้มก่อนการ "ควบรวม", หากกำหนดการควบรวมก่อน จะปรากฏผล เช่น $ cat yy.txt xx.txt 2>&1 1>log cat: xx.txt: No such file or directory ผลลัพธ์ (ข้อมูลจาก yy.txt) เขียนลงในแฟ้ม log (ตาม 1>log) แต่กำหนดทิศทางของข่าวสารความผิดพลาดไว่ไม่ถูกต้อง เชลล์จึงส่งออกทางหน้าจอ (ซึ่งเป็น default) หรือเรียกให้เป็นภาษาวิชาการได้ว่า "ไม่สามารถทำ forward reference ได้" การเปลี่ยนทิศทางในบรรทัดคำสั่ง ------------------------ เมื่อเพิ่ม redirection operator เข้าในบรรทัดคำสั่ง ในบางสถานการณ์อาจทำให้ดูซับซ้อนและยากต่อการทำความเข้าใจ จำเป็นต้องอ่านคู่มือ เพื่อดูรูปแบบการใช้งานจากหัวข้อ Synopsis (สาระสำคัญ) และหัวข้อคำอธิบาย (Description) เช่น คำสั่ง cat CAT(1) User Commands CAT(1) NAME cat - concatenate files and print on the standard output (นำข้อมูลในแฟ้มที่กำหนดมาต่อกัน แล้วส่งผลลัพธ์ออกทางstandard output) SYNOPSIS cat [OPTION]... [FILE]... DESCRIPTION Concatenate FILE(s), or standard input, to standard output. นำข้อมูลในแฟ้ม หรือ ข้อมูลจาก standard input มาต่อกัน ส้งผลลัพธ์ออกทาง standard output ตัวอย่างที่ ๑ ---------- $ cat yy.txt วิเคราะห์บรรทัดคำสั่ง: cat <ชื่อแฟ้ม> คำสั่ง cat ตามด้วยชื่อแฟ้ม หมายความว่าให้แสดงข้อมูลในแฟ้มทาง stdout ตัวอย่างที่ ๒ ---------- $ cat < yy.txt วิเคราะห์บรรทัดคำสั่ง: cat < yy.txt คำสั่ง redirection ชื่อแฟ้ม operator คำสั่ง cat ไม่มีชื่อแฟ้ม หมายความว่า ให้อ่านข้อมูลจาก standard input < yy.txt กำหนดให้เปลี่ยนทิศทางรับข้อข้อมูลเข้าจากแฟ้ม yy.txt ตัวอย่างที่ ๓ ---------- $ cat > yy.txt วิเคราะห์บรรทัดคำสั่ง: cat > yy.txt คำสั่ง redirection ชื่อแฟ้ม operator คำสั่ง cat ไม่มีชื่อแฟ้ม หมายความว่า ให้อ่านข้อมูลจาก standard input > yy.txt กำหนดให้เปลี่ยนทิศทางผลลัพธ์ไปยังแฟ้ม yy.txt ซึ่งเท่ากับ เป็นการคัดลอกของที่ผู้ใช้พิมพ์ทางแป้นพิมพ์ลงในแฟ้ม yy.txt เนื่องจาก standard input (รวมทั้ง standard output และ standard error) เป็น stream หรือข้อมูลไม่จำกัด โปรแกรม cat จึงไม่มีทางรู้ว่าข้อมูลจะหมดสิ้นเมื่อไร ผู้ใช้จึงต้องเป็นผู้บอก โดยส่งรหัสแสดงการสิ้นสุดของ stream รหัสนี้นิยมเรียกว่ารหัสปิดแฟ้ม (end-of-file, eof) ในระบบปฏิบัติการ Unix กำหนดให้กดแป้น Ctrl-D เพื่อสร้างรหัส EOT (End Of Transmission) โปรแกรม cat จะได้ทำการปิดแฟ้มและเลิกทำงาน