- เหตุผลที่การทดสอบอัตโนมัติล้มเหลวเฉพาะตอน 00:30 เป็นเพราะ
man -w แสดง สตริง stderr ที่ไม่คาดคิดอย่าง gimme gimme gimme ออกมาด้วย
- สตริงนี้เป็น อีสเตอร์เอกก์ ของ
man ซึ่งจะปรากฏเมื่อรันโดยไม่มีหน้าแมนนวล หรือใช้ -w และเวลาท้องถิ่นเป็น 00:30
- ข้อความนี้มาจากเพลง “Gimme! Gimme! Gimme! (A Man After Midnight)” ของ ABBA และมุกในทวีตปี 2011 ถูกนำไปใส่ในโค้ด
man-db
man -w แสดง manpath และมี exit code เป็น 0 จึงอาจถูกใช้ในงานอัตโนมัติได้ แต่อีสเตอร์เอกก์นี้อาจทำให้การ parse เอาต์พุตพังได้
man-db แก้ก่อนโดยไม่ให้ทำงานใน man -w และภายหลังตัดสินใจลบอีสเตอร์เอกก์นี้ออกทั้งหมดใน man-db 2.8.0
การทดสอบที่ล้มเหลวเฉพาะตอน 00:30
- การทดสอบอัตโนมัติทำงานปกติในเวลาส่วนใหญ่ แต่ล้มเหลวเฉพาะเมื่อรันตอน 00:30
- สาเหตุโดยตรงคือมีสตริงที่ไม่คาดคิดถูกเพิ่มเข้ามาใน
stderr
gimme gimme gimme
- คำสั่งที่ใช้ในการทดสอบคือ
man -w และมีวัตถุประสงค์เพื่อดึง manpath ปัจจุบัน
อีสเตอร์เอกก์ที่อยู่ใน man
- สตริงดังกล่าวเป็น อีสเตอร์เอกก์ ที่อยู่ในคำสั่ง
man
- เงื่อนไขการทำงานมีดังนี้
- รัน
man โดยไม่ระบุหน้าแมนนวล
- หรือรัน
man -w
- เวลาท้องถิ่นเป็น 00:30
- หากตรงตามเงื่อนไข จะพิมพ์
gimme gimme gimme ไปยัง stderr
# date +%T -s "00:30:00"
00:30:00
# man -w
gimme gimme gimme
/usr/local/share/man:/usr/share/man:/usr/man
- แม้ในกรณีนี้ exit code ก็ยังคงเป็น 0
พฤติกรรมที่คาดหวังเดิม
- เอาต์พุตปกติของ
man -w ควรคืนเฉพาะ path สำหรับค้นหาหน้าแมนนวลเท่านั้น
# man -w
/usr/local/share/man:/usr/share/man:/usr/man
# echo $?
0
- เมื่อรัน
man โดยไม่มีหน้า ควรถามว่าต้องการหน้าแมนนวลใด และคืน exit code เป็น 1 ซึ่งเป็นพฤติกรรมที่คาดหวัง
# man
What manual page do you want?
# echo $?
1
- เนื่องจาก
man -w แสดง path สำหรับค้นหา จึงอาจถูกใช้เป็นองค์ประกอบในการตรวจสอบการติดตั้งหน้าแมนนวลหรือในระบบทดสอบอัตโนมัติได้
โค้ดและขอบเขตของดิสทริบิวชัน
- พบสตริงนี้ใน RHEL, OpenSUSE, Fedora, Debian เป็นต้น และไม่ใช่พฤติกรรมเฉพาะของดิสทริบิวชันใดดิสทริบิวชันหนึ่ง
- สามารถตรวจสอบการมีอยู่ของสตริงได้ด้วยการ
grep จากไบนารี
- เอาต์พุตเกิดจากโค้ด
src/man.c ของ man-db
time_t now = time (NULL);
struct tm *localnow = localtime (&now);
if (localnow &&
localnow->tm_hour == 0 && localnow->tm_min == 30)
fprintf (stderr, "gimme gimme gimme\n");
สตริงที่มาจากเพลงของ ABBA และทวีต
gimme gimme gimme เป็นสตริงที่มาจากเพลง “Gimme! Gimme! Gimme! (A Man After Midnight)” ของ ABBA
- Marnanel Thurman เสนอแบบล้อเล่นในทวีตปี 2011 ว่า หากรัน
man ตอน 00:01 ควรแสดง gimme gimme gimme
- ผู้ดูแล
man ได้นำข้อเสนอนั้นไปใส่ในโค้ดจริง
- คอมมิตแรกเริ่มทำงานตอน 00:01 และภายหลังมีการเสริมในคอมเมนต์ว่าถูกเปลี่ยนเป็น 00:30 พร้อมข้อความคอมมิตว่า “half past twelve”
การแก้ไขและการลบออก
- Colin Watson ผู้ดูแล
man-db แก้ก่อนด้วย คอมมิต 84bde8 เพื่อไม่ให้อีสเตอร์เอกก์นี้ทำงานใน man -w
- หลังจากนั้น Colin Watson ได้ใช้ คอมมิตสำหรับลบ อีสเตอร์เอกก์นี้ออกทั้งหมด
- อีสเตอร์เอกก์ที่ถูกลบนี้มีกำหนดจะหายไปใน man-db 2.8.0 ที่วางแผนไว้
- ผู้ดูแลตัดสินว่า แม้อีสเตอร์เอกก์นี้จะทำให้บางคนหัวเราะได้ แต่ก็สร้างความรำคาญให้บางคน และระยะเวลา 6 ปีก็นานพอแล้ว
3 ความคิดเห็น
ถ้าจะใส่ Easter egg แบบนี้ การตรวจสอบสักครั้งว่า standard input/output เป็น TTY หรือไม่ก็เป็นวิธีที่ดีครับ ถ้าเป็นเชลล์สคริปต์ก็ตรวจสอบได้ด้วย
[[ -t 1]]แปล
manเป็น "ผู้ชาย" สินะครับ 555ความคิดเห็นจาก Hacker News
เมื่อก่อน ตอนที่การแพทย์ทางไกลยังไม่แพร่หลายเหมือนตอนนี้ ผมเคยทำ เว็บแอปการแพทย์ทางไกล ซึ่งมีฟีเจอร์ให้คนไข้กรอกแบบสอบถามออนไลน์แล้วแพทย์ดูคำตอบได้
ตอนออนบอร์ดหลายแผนก เรามีลอจิกที่ค่อนข้างทรงพลังสำหรับควบคุมแบบมีเงื่อนไขว่าจะให้แสดงคำถามหรือไม่ พอผมกำลังทำฟีเจอร์สำหรับคลินิกจิตเวชใหม่ แล้วพบว่าคำถามที่ควรแสดงกลับไม่แสดง ระหว่างดีบักเลยใส่ข้อความดีบักไร้สาระและออกแนวหงุดหงิดไว้ข้างคำถามเต็มไปหมด
ผมคิดว่าแก้ปัญหาและเก็บกวาดเรียบร้อยแล้ว แต่ดันเหลือข้อความหนึ่งไว้ ซึ่งเมื่อมีชุดคำตอบบางแบบจะขึ้นตัวอักษรสีแดงใหญ่ ๆ ว่า I SEE YOU!!! แล้วคนไข้ที่กำลังกรอกแบบประเมินภาวะหวาดระแวงของคลินิกจิตเวชที่เพิ่งเปิดใหม่ก็ไปเจอมันเข้า
หลังจากนั้นผมเริ่มใช้สัญลักษณ์ดีบักอย่าง
aaaหรือ111แทนเท่าที่จำได้น่าจะเป็นหลังเหตุการณ์ WD อันเลื่องชื่อ ที่ในโค้ดทดสอบคำว่า “western digital” ถูกเปลี่ยนเป็น “woodly doodly” แล้วเผลอปล่อยออกไป
ระหว่างพัฒนา มันพังเฉพาะในสถานการณ์ที่เจาะจงมาก ๆ และดูเหมือนเป็นเงื่อนไขประหลาดที่เกิดเฉพาะในสภาพแวดล้อมพัฒนาเครื่องตัวเอง ผมเลยใส่ข้อความผิดพลาดประมาณว่า “watch and amaze while the application eats itself!” เป็นประโยคที่ได้แรงบันดาลใจจากข้อผิดพลาดที่เคยเห็นในเกม Discworld สำหรับ PlayStation
แต่พอขึ้น production ปรากฏว่าเงื่อนไขที่ทำให้เกิดข้อผิดพลาดนั้นไม่ได้เฉพาะเจาะจงอย่างที่คิด ฝ่ายซัพพอร์ตลูกค้าแทบล่มเพราะมีคนหลายร้อยโทรมาคิดว่าเงินหาย และคนที่ใช้ฟีเจอร์นี้เป็น นักพนันรายใหญ่ ที่ลงเงินก้อนโต ผู้บริหารเลยไม่ปลื้มเลยสักนิด
โชคดีที่ไม่ได้ถูกไล่ออกและแก้ได้อย่างรวดเร็ว แต่ตอนนั้นรู้สึกเหมือนมีมีดจ่อคอ เป็นบทเรียนราคาแพงในสัปดาห์นั้น จากหนึ่งในงานแรก ๆ ของผมเมื่อเกือบ 20 ปีก่อน
# MULTIPASS!https://github.com/workarea-commerce/workarea/blob/master/co...
บริบทคือ The 5th Element เป็นหนังที่ยอดเยี่ยม สุนัขของพี่สาวผมชื่อ Leeloo Dallas Multipass และมันเป็นหมาตัวโปรดของผม และผมเป็นนักพัฒนาคนแรกที่สร้างฟีเจอร์คิวรีค้นหา
ProductMultipassผมยังได้รู้ด้วยว่าคอมเมนต์ตลก ๆ ทำให้นักพัฒนาคนอื่นชอบผลิตภัณฑ์มากขึ้น
เพราะก่อนคอมมิตจะหาได้ง่ายด้วย
grepและถึงหลุดเข้า production ไป ก็ไม่ใช่สตริงที่ไม่รู้ที่มาที่ไปเสียทีเดียวโชคดีที่ไม่ได้เป็นอะไรน่าอายมาก ทุกวันนี้ก่อนคอมมิตและ push ผมจะดู
git diffเป็นการตรวจครั้งสุดท้ายเสมอ และพยายามค้นหาprintหรือคำสั่งเอาต์พุตลักษณะเดียวกันของภาษานั้น ๆสมัยมัธยม เพื่อนผมมีนิสัยตั้งชื่อร่างงานแบบไม่เหมาะสม เวลาเราช่วยกันตรวจแก้ก็ขำดี แต่สุดท้ายครั้งหนึ่งเขาลืมเปลี่ยนชื่อกลับ ในคาบภาษาอังกฤษ ตอนครูเดินเก็บงาน เพื่อนผมมองกระดาษตัวเองแล้วจู่ ๆ ก็วิ่งออกไปบอกว่าจะเข้าห้องน้ำ จากนั้นไปห้องคอมพิวเตอร์เพื่อพิมพ์สำเนาใหม่ที่ไม่มีคำหยาบตัว 24 พอยต์อยู่บรรทัดบนสุด ผมแทบขำตาย
ถ้าซอฟต์แวร์เป็นของฟรีและผู้ดูแลไม่ได้รับค่าตอบแทน ผมมองว่า Easter egg สักสองสามอันเป็นราคาที่เล็กน้อย
แน่นอนว่า Colin ได้รับเงินอยู่ แต่หลัก ๆ แล้วไม่ได้รับเงินเพื่อดูแล
manโดยตรงบริษัทหนึ่งที่ผมเคยทำงานด้วย มีนักพัฒนาคนหนึ่งเคยใส่ประโยคในข้อตกลงการใช้งานว่าผู้ใช้โอนวิญญาณของตนให้บริษัท เจตนาคืออยากดูว่าผู้บริหารหรือฝ่ายกฎหมายตรวจข้อตกลงตามที่รับปากไว้หรือไม่ ซึ่งก็ไม่ได้ตรวจ และวิญญาณจำนวนมากก็ถูกจับไป
การเขียนโค้ดควรสนุก และการใช้โค้ดก็ควรสนุก คนเหล่านี้ทำได้ดีแล้วในความเห็นผม
แนวคิดที่ว่าโอเพนซอร์สต้องเย็นชาและจริงจังนั้นเกิดขึ้นเพราะบริษัทต่าง ๆ เข้ามาผลักดันเท่านั้น ถ้าผมทำโปรแกรมกับเพื่อน ผมคงใส่ Easter egg ไว้ตามจุดต่าง ๆ เพื่อเตือนให้รู้ว่าอีกฝั่งก็มีมนุษย์อยู่
คนที่เจอก็จะเป็นการบังเอิญเหยียบโดนเหมือนเจ้าของโพสต์ และ pipeline ของ continuous integration ของเจ้าของโพสต์ก็พัง ผมว่า Easter egg ไม่ใช่เครื่องมือที่ดีนักสำหรับเตือนว่า “อีกฝั่งก็มีมนุษย์อยู่”
อย่างน้อยก็นอกเหนือจากซอฟต์แวร์เพื่อความบันเทิง
โดยเฉพาะถ้าสิ่งที่ทำงานด้วยถูกล้อมรอบด้วยขั้นตอนราชการ ส่วนตัวแล้วที่ชอบที่สุดคือ Rick Roll ที่ผมซ่อนไว้ในซอร์สโค้ดของแอปพลิเคชันภาครัฐซึ่งผมเคยแก้ในงานคอนซัลต์เมื่อหลายปีก่อน มีแต่นักพัฒนาที่ทำงานกับซับซิสเต็มเฉพาะมาก ๆ เท่านั้นที่จะหาเจอ แต่ถ้าพบแล้วจะเข้าใจจากบริบทว่าทำไมมันถึงอยู่ตรงนั้น
นี่เป็นอีกเหตุผลหนึ่งที่ทำให้ยากจะไว้วางใจซอฟต์แวร์ที่รวมชิ้นส่วนหลายชิ้นซึ่งมีกระบวนการวิศวกรรมต่างกัน ในแอปพลิเคชันด้านความปลอดภัยของชีวิตหรือภารกิจสำคัญ
ตอนนี้ไม่มีอยู่แล้ว
Colin Watson ผู้พัฒนา
man-dbเห็นว่ามันสนุกพอแล้วและเรื่องราวก็คงไม่ถูกลืม จึง ลบ Easter egg ออกทั้งหมดhttps://git.savannah.gnu.org/cgit/man-db.git/commit/?id=b225...
เนื้อหาคือเราควรเก็บ Easter egg แบบนี้ไว้ เพราะท้ายที่สุดสิ่งเหล่านี้คือสิ่งที่ แยกมนุษย์ออกจากเครื่องจักร
บทความที่เกี่ยวข้อง:
Why does man print “gimme gimme gimme” at 00:30? (2017) - https://news.ycombinator.com/item?id=27994194 - กรกฎาคม 2021, 211 ความคิดเห็น
Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15747313 - พฤศจิกายน 2017, 159 ความคิดเห็น
Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15746972 - พฤศจิกายน 2017, 1 ความคิดเห็น
Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15742221 - พฤศจิกายน 2017, 1 ความคิดเห็น
เป็นไอเดียที่สนุก แต่ไม่ควรใส่ไว้ใน flow การทำงานปกติ เพราะจะสร้างความเสียหายให้ผู้ใช้
ถ้าเป็น
man -abbaอย่างที่ผู้เขียนต้นฉบับพูดไว้คงจะดีกว่าแต่ด้วยความผิดพลาด มันทำงานด้วยแม้ในกรณีที่ระบุ man page ด้วยแฟล็ก
--pathแทนชื่อหน้า$ man --abba --format=json["gimme", "gimme", "gimme"]อัปเดตนี้ทำให้ workflow ของผมพัง
manหลังเที่ยงคืนพอดีตอนเลิกใช้ระบบโทรศัพท์เก่า ผมติดตั้ง FreePBX ให้บริษัท
มีหมายเลขภายในไม่เยอะ เลยใช้ 1xx, 2xx, 3xx เป็นหมายเลขภายในแยกตามประเภทแล้วยังเหลือเลขอีกมาก และผมใส่ easter egg เล็ก ๆ ไว้ว่า ถ้ามีคนโทรไปหมายเลขภายใน 666 จะเล่นเสียงหัวเราะน่ากลัวของ Vincent Price ช่วงท้ายเพลง Thriller ของ Michael Jackson
หนึ่งหรือสองปีต่อมา เช้าตรู่วันหนึ่ง เพื่อนร่วมงานส่งข้อความมาว่าเหมือนโทรศัพท์ถูกแฮ็ก และไม่ว่าโทรไปที่ไหนก็ได้ยินเสียงน่ากลัว พอตรวจดูพบว่ามีบางอย่างผิดพลาด ทำให้ทุกสายถูกโอนไปยังหมายเลขภายในล่าสุดที่เพิ่มไว้คือ 666
แน่นอนว่าผู้คนไม่ได้รู้สึกว่า easter egg นั้นสนุก และรู้สึกถูกเยาะเย้ยจากเสียงหัวเราะนั้น
สงสัยว่ามีสมมติฐานไหมว่าทำไมถึงมีการทดสอบที่เรียก
manแบบไม่มี argumentเป้าหมายคือแค่ตรวจว่า
manติดตั้งอยู่หรือเปล่าหรือ? ถึงอย่างนั้นก็น่าจะทดสอบคำสั่งในแบบที่ใช้กันตามปกติ--pathต่อมาส่วนนี้ถูกแก้ และหลังจากนั้นอีก easter egg ทั้งหมดก็ถูกเอาออก
man -wmanให้ output ตามที่คาดไว้หรือไม่ถ้าจะตัดสินว่า
manจบการทำงานอย่างถูกต้องหรือไม่ ผมว่าควรเชื่อ exit codeการตัดสินจากความยาวของ
stderrนั้นไม่เสถียรเสมอ