2 คะแนน โดย GN⁺ 2024-10-05 | 3 ความคิดเห็น | แชร์ทาง WhatsApp
  • เหตุผลที่การทดสอบอัตโนมัติล้มเหลวเฉพาะตอน 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 ความคิดเห็น

 
tribela 2024-10-07

ถ้าจะใส่ Easter egg แบบนี้ การตรวจสอบสักครั้งว่า standard input/output เป็น TTY หรือไม่ก็เป็นวิธีที่ดีครับ ถ้าเป็นเชลล์สคริปต์ก็ตรวจสอบได้ด้วย [[ -t 1]]

 
y15un 2024-10-05

แปล man เป็น "ผู้ชาย" สินะครับ 555

 
GN⁺ 2024-10-05
ความคิดเห็นจาก Hacker News
  • เมื่อก่อน ตอนที่การแพทย์ทางไกลยังไม่แพร่หลายเหมือนตอนนี้ ผมเคยทำ เว็บแอปการแพทย์ทางไกล ซึ่งมีฟีเจอร์ให้คนไข้กรอกแบบสอบถามออนไลน์แล้วแพทย์ดูคำตอบได้
    ตอนออนบอร์ดหลายแผนก เรามีลอจิกที่ค่อนข้างทรงพลังสำหรับควบคุมแบบมีเงื่อนไขว่าจะให้แสดงคำถามหรือไม่ พอผมกำลังทำฟีเจอร์สำหรับคลินิกจิตเวชใหม่ แล้วพบว่าคำถามที่ควรแสดงกลับไม่แสดง ระหว่างดีบักเลยใส่ข้อความดีบักไร้สาระและออกแนวหงุดหงิดไว้ข้างคำถามเต็มไปหมด
    ผมคิดว่าแก้ปัญหาและเก็บกวาดเรียบร้อยแล้ว แต่ดันเหลือข้อความหนึ่งไว้ ซึ่งเมื่อมีชุดคำตอบบางแบบจะขึ้นตัวอักษรสีแดงใหญ่ ๆ ว่า I SEE YOU!!! แล้วคนไข้ที่กำลังกรอกแบบประเมินภาวะหวาดระแวงของคลินิกจิตเวชที่เพิ่งเปิดใหม่ก็ไปเจอมันเข้า
    หลังจากนั้นผมเริ่มใช้สัญลักษณ์ดีบักอย่าง aaa หรือ 111 แทน

    • ที่ Google มีข้อกำหนดให้ใส่ DO NOT SUBMIT ในสตริงสำหรับดีบัก และหลังจากมีสตริงดีบักหลุดไปในสภาพแวดล้อม production ก็มีการเพิ่มบอตไว้ตรวจเรื่องนี้
      เท่าที่จำได้น่าจะเป็นหลังเหตุการณ์ 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
      ผมยังได้รู้ด้วยว่าคอมเมนต์ตลก ๆ ทำให้นักพัฒนาคนอื่นชอบผลิตภัณฑ์มากขึ้น
    • ปกติผมใช้ชื่อย่อของตัวเองคู่กับ DEBUG เป็นสัญลักษณ์ดีบัก
      เพราะก่อนคอมมิตจะหาได้ง่ายด้วย grep และถึงหลุดเข้า production ไป ก็ไม่ใช่สตริงที่ไม่รู้ที่มาที่ไปเสียทีเดียว
    • ผมเคยคอมมิตข้อความดีบักแน่นอน และคิดว่าคนที่เขียนโค้ดส่วนใหญ่น่าจะเคยสักครั้ง
      โชคดีที่ไม่ได้เป็นอะไรน่าอายมาก ทุกวันนี้ก่อนคอมมิตและ push ผมจะดู git diff เป็นการตรวจครั้งสุดท้ายเสมอ และพยายามค้นหา print หรือคำสั่งเอาต์พุตลักษณะเดียวกันของภาษานั้น ๆ
      สมัยมัธยม เพื่อนผมมีนิสัยตั้งชื่อร่างงานแบบไม่เหมาะสม เวลาเราช่วยกันตรวจแก้ก็ขำดี แต่สุดท้ายครั้งหนึ่งเขาลืมเปลี่ยนชื่อกลับ ในคาบภาษาอังกฤษ ตอนครูเดินเก็บงาน เพื่อนผมมองกระดาษตัวเองแล้วจู่ ๆ ก็วิ่งออกไปบอกว่าจะเข้าห้องน้ำ จากนั้นไปห้องคอมพิวเตอร์เพื่อพิมพ์สำเนาใหม่ที่ไม่มีคำหยาบตัว 24 พอยต์อยู่บรรทัดบนสุด ผมแทบขำตาย
  • ถ้าซอฟต์แวร์เป็นของฟรีและผู้ดูแลไม่ได้รับค่าตอบแทน ผมมองว่า Easter egg สักสองสามอันเป็นราคาที่เล็กน้อย
    แน่นอนว่า Colin ได้รับเงินอยู่ แต่หลัก ๆ แล้วไม่ได้รับเงินเพื่อดูแล man โดยตรง
    บริษัทหนึ่งที่ผมเคยทำงานด้วย มีนักพัฒนาคนหนึ่งเคยใส่ประโยคในข้อตกลงการใช้งานว่าผู้ใช้โอนวิญญาณของตนให้บริษัท เจตนาคืออยากดูว่าผู้บริหารหรือฝ่ายกฎหมายตรวจข้อตกลงตามที่รับปากไว้หรือไม่ ซึ่งก็ไม่ได้ตรวจ และวิญญาณจำนวนมากก็ถูกจับไป

    • แบบนั้นอาจทำให้ ข้อตกลงการใช้งานทั้งหมดเป็นโมฆะ ได้
  • การเขียนโค้ดควรสนุก และการใช้โค้ดก็ควรสนุก คนเหล่านี้ทำได้ดีแล้วในความเห็นผม
    แนวคิดที่ว่าโอเพนซอร์สต้องเย็นชาและจริงจังนั้นเกิดขึ้นเพราะบริษัทต่าง ๆ เข้ามาผลักดันเท่านั้น ถ้าผมทำโปรแกรมกับเพื่อน ผมคงใส่ Easter egg ไว้ตามจุดต่าง ๆ เพื่อเตือนให้รู้ว่าอีกฝั่งก็มีมนุษย์อยู่

    • เพราะมันถูกซ่อนไว้ คนส่วนใหญ่จึงจะไม่เจอ Easter egg นั้น
      คนที่เจอก็จะเป็นการบังเอิญเหยียบโดนเหมือนเจ้าของโพสต์ และ pipeline ของ continuous integration ของเจ้าของโพสต์ก็พัง ผมว่า Easter egg ไม่ใช่เครื่องมือที่ดีนักสำหรับเตือนว่า “อีกฝั่งก็มีมนุษย์อยู่”
      อย่างน้อยก็นอกเหนือจากซอฟต์แวร์เพื่อความบันเทิง
    • มีไม่กี่อย่างที่สนุกและน่าพอใจเท่า Easter egg ที่ซ่อนไว้อย่างดี
      โดยเฉพาะถ้าสิ่งที่ทำงานด้วยถูกล้อมรอบด้วยขั้นตอนราชการ ส่วนตัวแล้วที่ชอบที่สุดคือ Rick Roll ที่ผมซ่อนไว้ในซอร์สโค้ดของแอปพลิเคชันภาครัฐซึ่งผมเคยแก้ในงานคอนซัลต์เมื่อหลายปีก่อน มีแต่นักพัฒนาที่ทำงานกับซับซิสเต็มเฉพาะมาก ๆ เท่านั้นที่จะหาเจอ แต่ถ้าพบแล้วจะเข้าใจจากบริบทว่าทำไมมันถึงอยู่ตรงนั้น
    • Easter egg ที่สนุกสำหรับบางคน อาจเป็น ทริกเกอร์ความผิดปกติแบบไม่กำหนดแน่นอน ที่สร้างผลลัพธ์จริงในเวิร์กโฟลว์ของอีกคนหนึ่งได้
      นี่เป็นอีกเหตุผลหนึ่งที่ทำให้ยากจะไว้วางใจซอฟต์แวร์ที่รวมชิ้นส่วนหลายชิ้นซึ่งมีกระบวนการวิศวกรรมต่างกัน ในแอปพลิเคชันด้านความปลอดภัยของชีวิตหรือภารกิจสำคัญ
  • ตอนนี้ไม่มีอยู่แล้ว
    Colin Watson ผู้พัฒนา man-db เห็นว่ามันสนุกพอแล้วและเรื่องราวก็คงไม่ถูกลืม จึง ลบ Easter egg ออกทั้งหมด
    https://git.savannah.gnu.org/cgit/man-db.git/commit/?id=b225...

    • ผมเคยอ่านคอมเมนต์สวยงามอันหนึ่งในการถกประเด็นนี้ ซึ่งตอนนี้หาไม่เจอแล้ว
      เนื้อหาคือเราควรเก็บ Easter egg แบบนี้ไว้ เพราะท้ายที่สุดสิ่งเหล่านี้คือสิ่งที่ แยกมนุษย์ออกจากเครื่องจักร
    • ผมเพิ่งลองบน Raspberry Pi รุ่นเก่าแล้วยังมีอยู่ เป็นระบบที่อิง Debian 9 Stretch
  • บทความที่เกี่ยวข้อง:
    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 อย่างที่ผู้เขียนต้นฉบับพูดไว้คงจะดีกว่า

    • จากคำตอบแรก เดิมทีตั้งใจให้ทำงานเฉพาะในสถานการณ์ error คือเมื่อไม่ได้ระบุหน้า
      แต่ด้วยความผิดพลาด มันทำงานด้วยแม้ในกรณีที่ระบุ man page ด้วยแฟล็ก --path แทนชื่อหน้า
    • $ man --abba --format=json
      ["gimme", "gimme", "gimme"]
    • ถูกเอาออกแล้ว ดูเพิ่มเติม: https://news.ycombinator.com/item?id=41738239
  • อัปเดตนี้ทำให้ workflow ของผมพัง

    • อัปเดตนี้ช่วยแก้ workflow ของผมต่างหาก เพราะผมต้องใช้ man หลังเที่ยงคืนพอดี
  • ตอนเลิกใช้ระบบโทรศัพท์เก่า ผมติดตั้ง FreePBX ให้บริษัท
    มีหมายเลขภายในไม่เยอะ เลยใช้ 1xx, 2xx, 3xx เป็นหมายเลขภายในแยกตามประเภทแล้วยังเหลือเลขอีกมาก และผมใส่ easter egg เล็ก ๆ ไว้ว่า ถ้ามีคนโทรไปหมายเลขภายใน 666 จะเล่นเสียงหัวเราะน่ากลัวของ Vincent Price ช่วงท้ายเพลง Thriller ของ Michael Jackson
    หนึ่งหรือสองปีต่อมา เช้าตรู่วันหนึ่ง เพื่อนร่วมงานส่งข้อความมาว่าเหมือนโทรศัพท์ถูกแฮ็ก และไม่ว่าโทรไปที่ไหนก็ได้ยินเสียงน่ากลัว พอตรวจดูพบว่ามีบางอย่างผิดพลาด ทำให้ทุกสายถูกโอนไปยังหมายเลขภายในล่าสุดที่เพิ่มไว้คือ 666
    แน่นอนว่าผู้คนไม่ได้รู้สึกว่า easter egg นั้นสนุก และรู้สึกถูกเยาะเย้ยจากเสียงหัวเราะนั้น

  • สงสัยว่ามีสมมติฐานไหมว่าทำไมถึงมีการทดสอบที่เรียก man แบบไม่มี argument
    เป้าหมายคือแค่ตรวจว่า man ติดตั้งอยู่หรือเปล่าหรือ? ถึงอย่างนั้นก็น่าจะทดสอบคำสั่งในแบบที่ใช้กันตามปกติ

    • อ่านคำตอบแล้ว ดูเหมือนว่า easter egg จะทำงานโดยไม่ได้ตั้งใจด้วยตอนส่งหน้าที่จะโหลดผ่าน --path
      ต่อมาส่วนนี้ถูกแก้ และหลังจากนั้นอีก easter egg ทั้งหมดก็ถูกเอาออก
    • คำถามใน Stack Overflow เองดูเหมือนจะเป็น คำถามตั้งใจปั้นขึ้น เพื่อเปิดทางให้คนอื่นเล่าเรื่องของตัวเองแบบสาธารณะ
    • ในคอมเมนต์ของคำถาม Stack Overflow ที่ลิงก์ไว้มีอธิบายละเอียดแล้ว สรุปสั้น ๆ คือเพราะต้องการ manpath: man -w
    • อาจเป็น automated test ประเภทตรวจว่า build image ติดตั้งถูกต้อง และ man ให้ output ตามที่คาดไว้หรือไม่
  • ถ้าจะตัดสินว่า man จบการทำงานอย่างถูกต้องหรือไม่ ผมว่าควรเชื่อ exit code
    การตัดสินจากความยาวของ stderr นั้นไม่เสถียรเสมอ