# การเขียนโปรแกรมเชลล์ (3)

### การเปลี่ยนแปลงทิศทางของช่องทางการสื่อสาร I/O redirection

ในการสื่อสารระหว่าง terminal กับตัว host ของคอมพิวเตอร์จะมีช่องทางที่ใช้กันอยู่ 3 ช่องทางซึ่งก็คือ STDIN (ช่องทางรับข้อมูลมาตรฐาน), STDOUT (ช่องทางแสดงผลลัพธ์มาตรฐาน) และ STDERR (ช่องทางแสดงผลลัพธ์ที่เป็นข้อผิดพลาดมาตรฐาน)

ที่กล่าวว่าเป็นการสื่อสารระหว่างเทอร์มินัลกับตัวโฮสต์นั้น เนื่องจากในสมัยก่อนจากการออกแบบยูนิกซ์ในสมัยที่เครื่อง PDP-11 กำลังรุ่งเรือง การจะใช้งานคอมพิวเตอร์แบบนี้จะต้องทำการติดต่อผ่านเครื่อง teletype ซึ่งมีลักษณะคล้ายเครื่อง พิมพ์ดีดไฟฟ้า (หากใครมีหนังสือ Road Ahead ก็สามารถเห็นภาพของบิลล์ เกตส์ กับ พอลล์ อัลเลน กำลังเล่นเครื่อง teletype ที่ว่านี้ได้) ตัว teletype นี้เป็นเครื่องมือที่เรียกว่า "เทอร์มินัล" แบบแรกๆ ดังนั้นจึงเป็นไปได้ว่าช่องทางรับข้อมูลมาตรฐานอาจไม่ใช่คีย์บอร์ดที่ต่ออยู่กับตัวซีพียู หรือช่องทางแสดงผลลัพธ์มาตรฐานอาจไม่ใช่มอนิเตอร์ที่ต่ออยู่กับตัวซีพียูดังที่คุณเห็นอยู่ทั่วไปจากเครื่องคอมพิวเตอร์ในปัจจุบัน และแน่นอนว่าไม่ได้มีการต่อเทอร์มินัลเข้ากับโฮสต์ เพียงเครื่องเดียวระบบยูนิกซ์จะต้องถูกออกแบบให้สามารถจัดการกับเทอร์มินัลจำนวนนับร้อยและ มีรูปแบบการใช้งานที่แตกต่างกันได้ (เทอร์มินัลแต่ละเครื่องอาจมีรูปแบบการใช้งานที่ต่างกัน ตามยี่ห้อของผู้ผลิต -- เช่นปุ่มลบตัวอักษร อาจวางไว้ที่ตำแหน่งต่างกัน หรือเทอร์มินัลบางเครื่องก็อาจไม่มีปุ่มลบตัวอักษรนี้เลยก็ได้ ต้องใช้ปุ่ม ฟังก์ชั่นพิเศษแทน) การแสดงผลลัพธ์ออกมาอาจไม่ได้แสดงผ่านทางจอภาพ แต่เป็น กลายเป็นการพิมพ์ผลลัพธ์ผ่านทางเครื่องพิมพ์ออกมาแทน นอกจากนี้ช่องทางการสื่อสารทั้งสามช่องทางจะต้องสามารถทำการเปลี่ยนแปลงได้ตลอดเวลา เช่นตามปกติ อาจแสดงผลลัพธ์ทางจอภาพ แต่ก็สามารถเปลี่ยนให้แสดงผลลัพธ์เป็นการพิมพ์ ผลลัพธ์ออกมาทางเครื่องพิมพ์ หรือไม่ก็เปลี่ยนเป็นการเก็บผลลัพธ์ลงไปในไฟล์ก็ได้

ทั้งนี้ความสามารถเรื่องของการบริหารเรื่องของเทอร์มินัลหรือเรื่องของการเปลี่ยนทิศทางของช่องทางสื่อสาร (I/O redirection) ไม่ได้เป็นความสามารถจากโปรแกรมแอพพลิเคชั่น แต่เป็นความสามารถจากตัวระบบปฏิบัติการเอง

ลีนุกซ์ได้รับอิทธิพลมาจากระบบยูนิกซ์ จึงยังคงความสามารถเกี่ยวกับเรื่องของการบริหารเทอร์มินัลและการเปลี่ยนทิศทางของช่องทางสื่อสารไว้อย่างครบถ้วน เราสามารถสั่งทำการเปลี่ยนแปลงช่องทางการสื่อสารเหล่านี้ได้จากเชลล์ตลอดเวลา

### การเปลี่ยนแปลงช่องทางการแสดงผลลัพธ์ออก (standard output redirection)

เราจะศึกษาจากการใช้งานคำสั่ง "cat" ซึ่งจะรอรับข้อมูลจากคีย์บอร์ดแล้วแสดงผลลัพธ์กลับมาทางจอภาพ ดังนั้นในที่นี้ STDIN คือคีย์บอร์ด และ STDOUT คือจอภาพหรือมอนิเตอร์

    $ cat
    This is first line 		: พิมพ์ข้อความ "This is first line"
    This is first line		: cat แสดงผลลัพธ์ คือข้อความที่พึ่งพิมพ์ลงไป
    This is second line		: พิมพ์ข้อความ "This is second line"
    This is second line		: cat แสดงผลลัพธ์ คือข้อความที่พึ่งพิมพ์ลงไป

ต่อไปนี้เราจะเปลี่ยนช่องทางแสดงผลลัพธ์ของโปรแกรม ซึ่งปกติแสดงออกมาที่จอภาพให้ไปเก็บลงไฟล์แทน

    $ cat > myfile
    This is first line		: พิมพ์ข้อความ "This is first line"
    This is second line		: พิมพ์ข้อความ "This is second line"

จะเห็นว่าคราวนี้โปรแกรม cat ไม่แสดงผลลัพธ์ออกมาให้เหมือนตัวอย่างแรก ซึ่งเป็น เพราะว่าโปรแกรม cat ได้ทำการเก็บผลลัพธ์ลงไปในไฟล์ที่ชื่อ "myfile" แทน นั่นคือ ตอนนี้ STDOUT ได้ถูกเปลี่ยนเป็นไฟล์ "myfile" แล้ว นั่นคือเราสามารถใช้เครื่องหมายมากกว่า ">" ทำการเปลี่ยนช่องทางการแสดงผลลัพธ์ได้ การใช้เครื่องหมายมากกว่า ">" จะเป็นการเขียนทับไฟล์ที่ระบุลงไป แต่ถ้าเราต้องการให้เขียนผลลัพธ์ไปต่อท้ายข้อมูลเดิมที่มีอยู่แล้วในไฟล์ ก็สามารถทำได้โดยการใช้เครื่องหมายมากกว่าซ้อนกันสองตัว ">>" ดังตัวอย่าง

    $ cat >> myfile

เราสามารถตรวจสอบว่าโปรแกรม cat ได้ทำการเก็บผลลัพธ์ไว้ในไฟล์ "myfile" จริงได้โดยใช้คำสั่ง $ cat This is first line This is second line

### การเปลี่ยนแปลงช่องทางการนำข้อมูลเข้า (standard input redirection)

เราจะทำการศึกษาจากการใช้งานคำสั่ง "sort" การใช้งานคำสั่ง sort โดยปกติจะทำการรับข้อมูลเข้าจากคีย์บอร์ดแล้วแสดงผลลัพธ์กลับออกมาทางจอภาพ ดังนั้นในที่นี้ STDIN ก็คือ คีย์บอร์ดและ STDOUT ก็คือ มอนิเตอร์

    $ sort
    Peter				: พิมพ์ Peter
    Mary				: พิมพ์ Mary
    John				: พิมพ์ John เสร็จแล้วกด Ctrl-D
    John				: Sort ทำการจัดเรียงข้อมูลให้ใหม่
    Mary
    Peter

ให้คุณทำการสร้างไฟล์ชื่อ "namelist" เพื่อเตรียมไว้ให้กับโปรแกรม sort

    $ cat > namelist
    Peter				: พิมพ์ Peter
    Mary				: พิมพ์ Mary
    John				: พิมพ์ John เสร็จแล้วกด Ctrl-D

คราวนี้คุณสามารถทำการเปลี่ยนทิศทางของช่องทางการนำข้อมูลเข้าจาก คีย์บอร์ด ไปเป็นนำข้อมูลเข้ามาจากไฟล์ที่ชื่อ "namelist" นี้ได้ ตามตัวอย่างต่อไปนี้

    $ sort < namelist
    John
    Mary
    Peter

จะเห็นว่าเราสามารถใช้เครื่องหมายน้อยกว่า "<" เพื่อทำการเปลี่ยนช่องทางการนำ ข้อมูลเข้าได้ กรณีนี้ STDIN จะเปลี่ยนไปเป็นไฟล์ที่ชื่อ "namelist"

พิเศษ : การเปลี่ยนทั้ง STDIN และ STDOUT พร้อมกัน
เราจะศึกษาเรื่องนี้ ได้จากโปรแกรม sort ตามตัวอย่างต่อไปนี้

    $ sort < namelist > sortlist

คำสั่งบรรทัดนี้ โปรแกรม sort จะรับข้อมูลจากไฟล์ "namelist" และเขียนผลลัพธ์ไปใส่ในไฟล์ "sortlist" ให้ใช้คำสั่ง cat ทำการตรวจข้อมูลที่อยู่ในไฟล์ "sortlist"

### การเปลี่ยนแปลงช่องทางแสดงข้อผิดพลาด (standard error redirection)

เมื่อเรียกใช้งานโปรแกรมในลีนุกซ์แล้วเกิดข้อผิดพลาดขึ้น โปรแกรมจะทำการแจ้งข้อผิดพลาดนั้นออกมาที่จอภาพตามปกติ แต่เราก็สามารถจะทำการเปลี่ยนทิศทางของการแสดงความผิดพลาดนั้นได้เช่นกัน ดังตัวอย่างต่อไปนี้

    $ ld
    ld: no input files

"ld" เป็นโปรแกรมที่ใช้ทำการลิงก์ออปเจ็คไฟล์ ซึ่งตามปกติจะต้องทำการระบุชื่อไฟล์ที่จะลิงก์ลงไปด้วย ดังนั้นเมื่อเรียกใช้งานเฉพาะโปรแกรม "ld" อย่างเดียว โปรแกรม จึงแจ้งข้อผิดพลาดว่า เราไม่ได้ใส่ชื่อไฟล์ที่จะลิงก์ลงไปด้วย

    $ ld > errfile			: การใช้เครื่องหมายมากกว่าเพื่อเปลี่ยนทิศทาง STDOUT ไม่มีผลกับการแจ้งความผิดพลาด
    ld: no input files		:
    $ ld 2>errfile			: เปลี่ยนทิศทาง STDERR โดยใช้ "2>"
    $ cat errfile			: แสดงข้อมูลในไฟล์ "errfile"
    ld: no input files		: ข้อมูลในไฟล์เป็นข้อความผิดพลาดที่ได้จาก "ld"

จะเห็นว่าหากเราต้องการเปลี่ยนทิศทางของการข้อความแสดงความผิดพลาด จะต้องทำการพิมพ์ "2> [ชื่อไฟล์]" ต่อท้ายคำสั่ง โดยให้ระวังว่า "2" กับ ">" จะต้องพิมพ์ติดกัน

### สรุป

-       Standard output redirection
        command > file
        หรือ
        command >> file

-       Standard input redirection
        command < file

-       Standard error redirection
        command 2>file
        หรือ
        command 2>>file

HTML developed by Kaiwal Development Team (kaiwal@geocities.com)