DEV Community

Vee Satayamas
Vee Satayamas

Posted on

2 2

เขียนโปรแกรมล้อ pipe ใน shell script

5 มีนาคม 2562

ใน shell script มัน pipe ต่อกันไปได้เรื่อย ๆ แบบนี้

cat input.txt | \
      prog1 x | \
      prog2 y | \
      prog3 z
Enter fullscreen mode Exit fullscreen mode
  • cat อ่านไฟล์ input1.txt แล้วก็ส่งออกมาทาง stdout ต่อมาก็ส่งเข้า prog1 ทาง stdin
  • prog1 อ่านข้อมูลจาก stdin ที่ cat ส่งมา; แล้วประมวลผลแล้วก็ส่งออกไป stdout
  • prog2 อ่านข้อมูลจาก stdin ที่ prog1 ส่งมา; แล้วประมวลผลแล้วก็ส่งออกไป stdout
  • prog3 อ่านข้อมูลจาก stdin ที่ prog2 ส่งมา; แล้วประมวลผลแล้วก็ส่งออกไป stdout
  • โดยที่ prog1 prog2 prog3 ก็รับค่า x y z เข้ามาทาง argument ด้วย

โปรแกรมแบบนี้จะเขียนใหม่เป็น Ruby ก็จะได้ประมาณนี้ หรือจะใช้ Java ก็จะคล้าย ๆ กัน

p read_file("input.txt").prog1(:x)
    .prog2(:y)
    .prog3(:z)
Enter fullscreen mode Exit fullscreen mode

พวก prog1 prog2 prog3 กลายเป็นชื่อ method ใน object ที่ดูจาก code ก็ไม่รู้ว่า object อะไร หรือกระทั่งตอนรันก็ไม่รู้ว่า prog1 ส่งข้อมูลอะไรออกมา

ถ้าเป็น shell script ก็ใส่ tee เข้าไปได้เลย

cat input.txt | \
      prog1 x | \
      prog2 y | \
      tee debug.txt | \
      prog3 z
Enter fullscreen mode Exit fullscreen mode

แล้วก็ไปเปิดดูไฟล์ debug.txt ทีหลังได้ โดยที่โปรแกรมโดยรวมก็ยังทำงานปกติ

แต่ถ้าเป็น Ruby หรือ Java ก็จะกลายเป็นท่ายาก เพราะว่าใส่ tee เข้าไปใน object ก็ยากเพราะไม่รู้ว่า object ไหน class อะไร ใส่ไปแล้วจะมั่วหรือเปล่า

โปรแกรมมันก็จะออกมาประมาณนี้แทน

tmp = read_file("input.txt").prog1(:x)
        .prog2(:y)
write_file(tmp)
p tmp.prog3(:z)
Enter fullscreen mode Exit fullscreen mode

ถ้าลองเปลี่ยนเป็น Clojure มันก็จะประมาณนี้

(-> (slurp "input.txt")
    (prog1 :x)
    (prog2 :y)
    (prog3 :z)
    println)
Enter fullscreen mode Exit fullscreen mode

พวก prog1 prog2 prog3 ก็จะเป็นแค่ function ธรรมดาแทนที่จะเป็น method

นอกจากนั้นก็ยังเขียน tee ขึ้นมาง่าย ๆ ได้แบบนี้

(defn tee [data path]
    (spit path data)
    data)
Enter fullscreen mode Exit fullscreen mode

แล้วก็เอา tee ไปแทรกได้แบบ shell script

(-> (slurp "input.txt")
    (prog1 :x)
    (prog2 :y)
    (tee "debug.txt")
    (prog3 :z)
    println)
Enter fullscreen mode Exit fullscreen mode

โปรแกรมทั้งหมดผมไม่ได้ลองรันจริง ๆ นะครับ อาจจะเจ๊งได้ จาก blog นี้ผมรู้สึกว่าตอบคำถามตัวเองได้ว่าทำไมเวลาเขียน Clojure หรือ Common Lisp ในโปรแกรมที่ค่อนข้างซับซ้อนแล้วรู้สึกสะดวกกว่า Ruby เอาจริงๆ จะเขียน Ruby หรือ Java ให้คล้าย ๆ Clojure ก็คงทำได้ แต่เขียนไปก็จะถูกเรียกว่าไม่ idiomatic อันนี้ก็เป็นอีกเหตุผลนึงให้เปลี่ยนภาษาเพราะว่าภาษามันพ่วงวัฒนธรรมมาด้วย

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more