ฟีเจอร์ JSON ของคำสั่ง Tree สร้างความวุ่นวายหลังจากฮาร์ดโค้ด File Descriptor 3

ทีมชุมชน BigGo
ฟีเจอร์ JSON ของคำสั่ง Tree สร้างความวุ่นวายหลังจากฮาร์ดโค้ด File Descriptor 3

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

ความวุ่นวายของ File Descriptor

Tree เวอร์ชัน 2.0.0 ได้แนะนำการแสดงผล JSON อัตโนมัติบน file descriptor 3 ซึ่งนักพัฒนาเรียกว่า stddata แนวคิดดูเหมือนจะง่าย: หาก file descriptor 3 มีอยู่ ให้แสดงผลข้อมูล JSON ที่นั่นโดยอัตโนมัติ อย่างไรก็ตาม สมมติฐานนี้กลับพิสูจน์ให้เห็นว่ามีปัญหาอย่างรวดเร็วเมื่อสคริปต์ที่มีอยู่เริ่มเสียหายโดยไม่คาดคิด

ปัญหาเกิดขึ้นเพราะสคริปต์เชลล์และกระบวนการระบบจำนวนมากส่ง file descriptor ต่างๆ ให้กับโปรแกรมเป็นประจำโดยไม่คาดหวังว่า descriptor เหล่านั้นจะทริกเกอร์พฤติกรรมพิเศษ สคริปต์ที่ทำงานได้อย่างเชื่อถือได้มานานหลายปีก็เริ่มสร้างเอาต์พุต JSON ที่ไม่ต้องการโดยไม่คาดคิด ทำให้เกิดปัญหาความเข้ากันได้อย่างแพร่หลาย

File descriptor คือช่องทางที่มีหมายเลขกำกับซึ่งโปรแกรมใช้เพื่ออ่านและเขียนข้อมูล โดย 0, 1, และ 2 ถูกสงวนไว้แบบดั้งเดิมสำหรับ standard input, output, และ error ตามลำดับ

ไทม์ไลน์เวอร์ชัน Tree Command:

  • เวอร์ชัน 2.0.0: เปิดตัวฟีเจอร์ JSON output อัตโนมัติบน file descriptor 3 ("stddata")
  • เวอร์ชัน 2.0.2: เปลี่ยนแปลงให้ต้องใช้ environment variable STDDATA_FD เนื่องจากปัญหาความเข้ากันได้

รายละเอียดทางเทคนิค:

  • ฟีเจอร์: JSON output บน file descriptor 3
  • Environment Variable: STDDATA_FD (จำเป็นต้องใช้ในเวอร์ชัน 2.0.2 ขึ้นไป)
  • ตัวอย่างการใช้งาน: STDDATA_FD=1 tree | from json
  • แพลตฟอร์ม: ปัจจุบันรองรับเฉพาะ Linux เท่านั้น
  • การพิจารณาในอนาคต: อาจเปลี่ยนไปใช้รูปแบบ BSON

การตอบโต้จากชุมชนและการวิจารณ์การออกแบบ

การตอบสนองของชุมชนนักพัฒนามาอย่างรวดเร็วและเป็นการวิจารณ์ หลายคนชี้ให้เห็นว่าแนวทางดังกล่าวละเมิดแบบแผน Unix ที่มีมายาวนานเกี่ยวกับวิธีที่โปรแกรมควรทำงาน การวิจารณ์หลักมุ่งเน้นไปที่การสร้างสมมติฐานเกี่ยวกับสภาพแวดล้อมแทนที่จะต้องการความตั้งใจที่ชัดเจนจากผู้ใช้

ในเวอร์ชัน 2.0.2 นักพัฒนาได้ยอมรับปัญหาและเปลี่ยนการใช้งานให้ต้องใช้ตัวแปรสภาพแวดล้อมที่เรียกว่า STDDATA_FD เพื่อเปิดใช้งานฟีเจอร์ อย่างไรก็ตาม การแก้ไขนี้ไม่ได้ทำให้นักวิจารณ์พอใจ ซึ่งโต้แย้งว่าตัวแปรสภาพแวดล้อมสร้างปัญหาของตัวเอง รวมถึงความขัดแย้งที่อาจเกิดขึ้นกับสคริปต์ที่มีอยู่ซึ่งอาจใช้ชื่อตัวแปรเดียวกันเพื่อวัตถุประสงค์ที่แตกต่างกัน

ตัวแปรสภาพแวดล้อมคือการตั้งค่าทั้งระบบที่โปรแกรมสามารถอ่านเพื่อปรับเปลี่ยนพฤติกรรมของตน

การถกเถียงเกี่ยวกับปรัชญาการออกแบบในวงกว้าง

ความขัดแย้งนี้ได้เน้นย้ำการอภิปรายที่ใหญ่กว่าเกี่ยวกับแนวปฏิบัติการพัฒนาซอฟต์แวร์สมัยใหม่ สมาชิกชุมชนบางคนแสดงความกังวลเกี่ยวกับนักพัฒนารุ่นใหม่ที่เพิกเฉยต่อแบบแผนที่ตั้งไว้โดยไม่พยายามเข้าใจความสำคัญทางประวัติศาสตร์ของแบบแผนเหล่านั้น การวิจารณ์ขยายไปเกินกรณีเฉพาะนี้ไปสู่ความกังวลที่กว้างขึ้นเกี่ยวกับการรักษาเสถียรภาพของระบบในขณะที่นักพัฒนาใหม่เข้าสู่สาขานี้

นี่เป็นความกังวลที่ใหญ่กว่าที่ฉันเริ่มเห็นในนักพัฒนารุ่นใหม่กลุ่มหนึ่งที่แบบแผนที่มีอยู่ถูกเพิกเฉยโดยไม่มีความพยายามที่จะเข้าใจว่าทำไมแบบแผนเหล่านั้นจึงมีอยู่

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

บริบททางเทคนิคและทางเลือก

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

นักพัฒนาบางคนสังเกตว่าโครงการอื่นๆ เช่น ไลบรารี libxo ของ FreeBSD ได้เพิ่มเอาต์พุตแบบมีโครงสร้างให้กับเครื่องมือระบบโดยใช้พารามิเตอร์บรรทัดคำสั่งมาตรฐานได้สำเร็จโดยไม่ทำให้เกิดปัญหาความเข้ากันได้

รูปแบบข้อมูลที่มีโครงสร้างเช่น JSON ช่วยให้โปรแกรมแลกเปลี่ยนข้อมูลในลักษณะที่โปรแกรมอื่นๆ ประมวลผลโดยอัตโนมัติได้ง่ายขึ้น

แนวทางทางเลือกที่ชุมชนแนะนำ:

  • การใช้ command-line flags แบบดั้งเดิม (--json-output=filename)
  • การใช้ชื่อโปรแกรมแยกต่างหาก
  • การทำตามแบบจำลอง libxo ของ FreeBSD ด้วยตัวเลือก --libxo
  • การใช้ standard output (stdout) สำหรับข้อมูล JSON

เทคโนโลยีที่เกี่ยวข้อง:

  • Nushell : shell สมัยใหม่ที่รองรับข้อมูลที่มีโครงสร้าง
  • PowerShell : shell แบบ object-oriented ของ Microsoft
  • libxo : ไลบรารีสำหรับผลลัพธ์ที่มีโครงสร้างของ FreeBSD
  • BSON : รูปแบบ Binary JSON ที่พิจารณาสำหรับเวอร์ชันในอนาคต

บทเรียนสำหรับการพัฒนาในอนาคต

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

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

อ้างอิง: Tree release notes, version 2.0.0