2 điểm bởi GN⁺ 2024-10-05 | 3 bình luận | Chia sẻ qua WhatsApp
  • Lý do bài kiểm thử tự động chỉ thất bại lúc 00:30 là vì man -w đã in kèm một chuỗi stderr ngoài dự kiến: gimme gimme gimme
  • Chuỗi này là một easter egg của man, xuất hiện khi chạy không có trang hướng dẫn hoặc dùng -w và giờ cục bộ là 00:30
  • Cụm này đến từ “Gimme! Gimme! Gimme! (A Man After Midnight)” của ABBA, và một câu đùa trên Twitter năm 2011 đã được đưa vào mã của man-db
  • man -w in ra manpath và mã thoát cũng là 0 nên có thể được dùng trong tự động hóa, nhưng easter egg này có thể làm hỏng việc phân tích cú pháp đầu ra
  • man-db trước tiên sửa để nó không kích hoạt với man -w, rồi sau đó quyết định loại bỏ hoàn toàn easter egg này trong man-db 2.8.0

Bài kiểm thử chỉ thất bại lúc 00:30

  • Bài kiểm thử tự động hoạt động bình thường vào hầu hết thời điểm, nhưng chỉ thất bại khi chạy lúc 00:30
  • Nguyên nhân trực tiếp là có thêm một chuỗi ngoài dự kiến trong stderr
gimme gimme gimme
  • Lệnh được dùng trong bài kiểm thử là man -w, nhằm lấy manpath hiện tại

Easter egg trong man

  • Chuỗi gây ra vấn đề là một easter egg có trong lệnh man
  • Điều kiện kích hoạt như sau
    • Chạy man mà không chỉ định trang hướng dẫn
    • Hoặc chạy man -w
    • Giờ cục bộ là 00:30
  • Khi thỏa điều kiện, gimme gimme gimme được in ra stderr
# date +%T -s "00:30:00"
00:30:00


# man -w
gimme gimme gimme
/usr/local/share/man:/usr/share/man:/usr/man
  • Ngay cả trong trường hợp này, mã thoát vẫn là 0

Hành vi vốn được kỳ vọng

  • Đầu ra bình thường của man -w là chỉ trả về đường dẫn tìm kiếm trang hướng dẫn
# man -w
/usr/local/share/man:/usr/share/man:/usr/man


# echo $?
0
  • Khi chạy man không có trang, hành vi kỳ vọng là hỏi người dùng muốn trang hướng dẫn nào và trả về mã thoát 1
# man
What manual page do you want?


# echo $?
1
  • man -w in ra đường dẫn tìm kiếm, nó có thể được dùng như một thành phần trong việc kiểm tra cài đặt trang hướng dẫn hoặc tự động hóa kiểm thử

Mã nguồn và phạm vi bản phân phối

  • Chuỗi này được tìm thấy trên RHEL, OpenSUSE, Fedora, Debian, v.v., nên không phải hành vi riêng của một bản phân phối cụ thể
  • Có thể kiểm tra sự tồn tại của chuỗi bằng cách grep chuỗi đó trong binary
  • Đầu ra được tạo ra từ mã src/man.c của 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");

Chuỗi đến từ bài hát của ABBA và một tweet

  • gimme gimme gimme là chuỗi đến từ “Gimme! Gimme! Gimme! (A Man After Midnight)” của ABBA
  • Trong một tweet năm 2011, Marnanel Thurman đã đùa rằng nếu chạy man lúc 00:01 thì nó nên in ra gimme gimme gimme
  • Người bảo trì man đã đưa đề xuất đó vào mã thật
  • Commit ban đầu kích hoạt lúc 00:01, và sau đó được bổ sung trong phần bình luận rằng nó đã đổi sang 00:30 cùng thông điệp commit “half past twelve”

Sửa lỗi và loại bỏ

  • Colin Watson, người bảo trì man-db, trước tiên đã sửa bằng commit 84bde8 để easter egg này không kích hoạt với man -w
  • Sau đó Colin Watson áp dụng commit loại bỏ hoàn toàn easter egg này
  • Easter egg bị loại bỏ dự kiến sẽ biến mất trong man-db 2.8.0 đã được lên kế hoạch
  • Người bảo trì cho rằng easter egg này từng khiến một số người bật cười nhưng cũng gây phiền toái cho một số người khác, và 6 năm là đủ lâu rồi

3 bình luận

 
tribela 2024-10-07

Nếu định thêm kiểu easter egg này, thì cũng là một cách hay khi kiểm tra xem đầu vào/đầu ra chuẩn có phải là TTY hay không. Nếu là shell script thì có thể kiểm tra bằng [[ -t 1]].

 
y15un 2024-10-05

man đã được dịch là nam giới rồi nhỉ haha

 
GN⁺ 2024-10-05
Bình luận trên Hacker News
  • Trước đây, trước khi khám chữa bệnh từ xa trở nên phổ biến như bây giờ, tôi từng làm một web app khám từ xa có chức năng để bệnh nhân điền bảng hỏi trực tuyến rồi bác sĩ xem câu trả lời.
    Trong quá trình onboard nhiều chuyên khoa, chúng tôi có một logic khá mạnh để điều khiển việc hiển thị câu hỏi theo điều kiện; khi đang làm tính năng cho một phòng khám tâm thần mới mà một câu hỏi lẽ ra phải hiện lại không hiện, tôi đã debug và chèn hàng loạt dòng chữ debug vô lý, hơi cáu kỉnh bên cạnh câu hỏi.
    Tôi tưởng đã sửa xong và dọn dẹp sạch sẽ, nhưng lại sót một dòng hiển thị I SEE YOU!!! bằng chữ đỏ to khi gặp một tổ hợp câu trả lời nhất định, và một bệnh nhân đã phát hiện ra nó khi đang làm bảng đánh giá hoang tưởng của phòng khám tâm thần mới mở.
    Từ sau đó tôi bắt đầu dùng các dấu debug kiểu aaa hoặc 111

    • Ở Google, người ta quy ước chuỗi dùng để debug phải có DO NOT SUBMIT, và sau khi các chuỗi debug lọt lên môi trường production thì họ thêm bot để kiểm tra việc này.
      Hình như là sau sự cố WD huyền thoại đó, khi trong mã kiểm thử, “western digital” bị đổi thành “woodly doodly” rồi vô tình được triển khai
    • Tôi cũng từng làm chuyện tương tự khi xây tính năng cho một trang cờ bạc, nơi người dùng có thể upload hàng loạt cược bằng một loại tệp đặc biệt.
      Trong lúc phát triển, nó chỉ hỏng ở một tình huống cực kỳ cụ thể và trông như một điều kiện kỳ quặc chỉ có ở môi trường dev local, nên tôi đã cho vào một thông báo lỗi kiểu “watch and amaze while the application eats itself!”. Câu này lấy cảm hứng từ một lỗi tôi từng thấy trong game Discworld trên PlayStation.
      Nhưng khi lên production, điều kiện kích hoạt lỗi đó lại không hề hiếm như tôi nghĩ, và bộ phận hỗ trợ khách hàng gần như tê liệt vì hàng trăm người gọi điện báo rằng tiền của họ biến mất. Những người dùng tính năng này đều là người đặt cược số tiền lớn, nên ban lãnh đạo tất nhiên chẳng hề vui chút nào.
      May mà tôi không bị sa thải và đã sửa rất nhanh, nhưng đúng là cảm giác lưỡi dao đã kề sát cổ. Ở một trong những công việc đầu tiên của tôi gần 20 năm trước, tôi đã học được một bài học cực kỳ đáng giá ngay trong tuần đó
    • Có một comment tôi đã để lại rất lâu trong tệp này, nhưng lead của dự án là người khá chuyên nghiệp nên đã xóa nó đi. Comment đó là # MULTIPASS!
      https://github.com/workarea-commerce/workarea/blob/master/co...
      Bối cảnh là thế này: The 5th Element là một bộ phim tuyệt vời, tên con chó của chị tôi là Leeloo Dallas Multipass và đó là con chó tôi yêu thích nhất, còn tôi chính là người đầu tiên viết tính năng truy vấn tìm kiếm ProductMultipass
      Tôi cũng nhận ra rằng những comment vui vẻ như vậy khiến các lập trình viên khác thích sản phẩm hơn
    • Tôi thường dùng chữ viết tắt tên mình cùng với DEBUG làm dấu debug.
      Như vậy sẽ dễ tìm bằng grep trước khi commit, và nếu lỡ vào production thì ít ra nó cũng không phải một chuỗi hoàn toàn bí hiểm
    • Tôi chắc chắn đã từng commit các thông báo debug, và có lẽ hầu hết ai viết code cũng ít nhất một lần như vậy.
      May là nội dung không quá xấu hổ, còn bây giờ tôi luôn xem git diff như bước kiểm tra cuối trước khi commit và push, đồng thời tìm các lệnh print hoặc dạng xuất tương tự trong ngôn ngữ đó.
      Hồi cấp ba, một người bạn của tôi có thói quen đặt tiêu đề bản nháp bài tập hơi thiếu đứng đắn; lúc sửa bài cho nhau thì rất buồn cười, nhưng rồi có lần cậu ấy quên đổi lại tiêu đề. Khi cô giáo đi quanh lớp để thu bài môn tiếng Anh, cậu ấy nhìn xuống tờ giấy của mình rồi đột nhiên lao ra ngoài lấy cớ đi vệ sinh, chạy tới phòng máy in lại một bản khác không có dòng chửi thề cỡ 24pt ở trên cùng, còn tôi thì cười suýt chết
  • Nếu phần mềm là miễn phí và người bảo trì không được trả tiền, thì tôi nghĩ vài easter egg là cái giá nhỏ phải trả.
    Tất nhiên Colin có được trả tiền, nhưng chủ yếu không phải để bảo trì man.
    Ở một công ty tôi từng làm, có một lập trình viên đã chèn vào điều khoản sử dụng một câu nói rằng người dùng chuyển nhượng linh hồn của mình cho công ty. Mục đích là để xem liệu ban điều hành hoặc bộ phận pháp lý có thực sự kiểm tra điều khoản như đã hứa hay không; và họ đã không kiểm tra, nên rất nhiều linh hồn đã bị thu giữ

    • Như vậy thì toàn bộ điều khoản sử dụng có thể bị vô hiệu
  • Việc lập trình nên vui, và viết code cũng nên vui. Tôi thấy những người này làm tốt đấy.
    Ý niệm rằng phần mềm nguồn mở phải lạnh lùng và nghiêm túc chỉ xuất hiện khi các công ty bắt đầu chi phối nó. Nếu tôi làm một chương trình cùng bạn mình, có lẽ tôi cũng sẽ cài easter egg ở đây ở kia để nhắc rằng phía bên kia cũng là con người

    • Vì được giấu đi nên đa số mọi người sẽ không bao giờ gặp những easter egg đó.
      Người gặp phải chúng thường là do vô tình đụng trúng như bài gốc, và trong bài gốc thì pipeline tích hợp liên tục đã bị hỏng. Tôi không nghĩ easter egg là công cụ tốt để nhắc rằng “phía bên kia cũng là con người”.
      Ít nhất là ngoài phần mềm giải trí
    • Hiếm có gì vui và thỏa mãn bằng một easter egg được giấu khéo.
      Nhất là khi thứ bạn đang làm bị bủa vây bởi những quy trình quan liêu. Cá nhân tôi thích nhất là một Rick Roll tôi từng giấu trong source code của một ứng dụng chính phủ mà tôi sửa khi làm tư vấn vài năm trước. Chỉ những lập trình viên làm trong một subsystem rất cụ thể mới có thể tìm thấy, nhưng nếu phát hiện ra thì họ sẽ hiểu vì sao nó nằm ở đó trong đúng ngữ cảnh
    • Một easter egg vui với người này có thể lại là một trình kích hoạt hành vi sai lệch không tất định gây ra hậu quả thực tế trong luồng công việc của người khác.
      Lại có thêm một lý do để khó mà tin tưởng phần mềm tích hợp nhiều mảnh ghép với các quy trình kỹ thuật khác nhau trong các ứng dụng liên quan đến an toàn tính mạng hoặc nhiệm vụ trọng yếu
  • Giờ thì nó không còn nữa.
    Colin Watson, nhà phát triển man-db, cho rằng như vậy là đủ vui rồi và câu chuyện cũng sẽ không bị lãng quên, nên đã xóa hoàn toàn easter egg
    https://git.savannah.gnu.org/cgit/man-db.git/commit/?id=b225...

    • Tôi từng đọc một bình luận rất đẹp trong phần thảo luận issue này, giờ thì không còn tìm thấy nữa.
      Nội dung nói rằng nên giữ lại những easter egg như thế này, vì rốt cuộc chính những thứ như vậy phân biệt con người với máy móc
    • Tôi vừa thử trên một con Raspberry Pi cũ và nó vẫn còn. Máy đó chạy Debian 9 Stretch
  • Bài liên quan:
    Why does man print “gimme gimme gimme” at 00:30? (2017) - https://news.ycombinator.com/item?id=27994194 - tháng 7 năm 2021, 211 bình luận
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15747313 - tháng 11 năm 2017, 159 bình luận
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15746972 - tháng 11 năm 2017, 1 bình luận
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15742221 - tháng 11 năm 2017, 1 bình luận

  • Ý tưởng thì vui đấy, nhưng không nên đưa vào luồng thực thi thông thường. Nó gây hại cho người dùng
    Như tác giả bài gốc nói, nếu là man -abba thì đã tốt hơn

    • Xem câu trả lời đầu tiên thì ban đầu nó chỉ định kích hoạt trong tình huống lỗi, tức là khi không chỉ định trang
      Nhưng do nhầm lẫn, nó cũng kích hoạt cả khi chỉ định man page bằng cờ --path thay vì tên trang
    • $ man --abba --format=json
      ["gimme", "gimme", "gimme"]
    • Đã bị gỡ bỏ. Tham khảo: https://news.ycombinator.com/item?id=41738239
  • Bản cập nhật này đã làm hỏng quy trình làm việc của tôi

    • Nhờ bản cập nhật này mà quy trình làm việc của tôi được sửa lại. Tôi cần dùng man sau nửa đêm
  • Khi loại bỏ hệ thống điện thoại cũ, tôi đã cài FreePBX cho công ty
    Vì không có nhiều số máy lẻ, nên sau khi dùng các dải 1xx, 2xx, 3xx cho từng loại máy lẻ vẫn còn thừa rất nhiều số, và tôi đã thêm một Easter egg nhỏ: nếu ai gọi vào máy lẻ 666 thì sẽ phát tiếng cười ma quái của Vincent Price ở cuối bài Thriller của Michael Jackson
    Sau 1–2 năm, vào một sáng sớm nọ, một đồng nghiệp nhắn tin rằng có vẻ điện thoại đã bị hack, vì gọi tới đâu cũng nghe thấy giọng nói đáng sợ. Kiểm tra thì hóa ra có gì đó bị lỗi và mọi cuộc gọi đều đang được chuyển tới máy lẻ 666, là máy lẻ cuối cùng được thêm vào
    Dĩ nhiên mọi người không thấy Easter egg đó buồn cười, mà còn cảm thấy bị xúc phạm bởi tiếng cười đó

  • Tôi tò mò không biết có giả thuyết nào về việc tại sao lại có bài kiểm thử gọi man mà không có đối số
    Mục tiêu chỉ là kiểm tra xem man đã được cài hay chưa sao? Dù vậy thì tôi vẫn nghĩ người ta thường kiểm thử lệnh theo cách dùng thông thường hơn

    • Đọc các câu trả lời thì có vẻ Easter egg đã vô tình kích hoạt cả khi truyền trang cần nạp qua --path
      Sau đó phần này đã được sửa, và về sau toàn bộ Easter egg cũng bị loại bỏ
    • Có vẻ chính câu hỏi trên Stack Overflow là một câu hỏi gượng ép để người khác có thể công khai kể lại câu chuyện của mình
    • Trong phần bình luận của câu hỏi Stack Overflow được liên kết đã bàn khá kỹ, và nói ngắn gọn là vì họ muốn manpath: man -w
    • Cũng có thể đó là một bài kiểm thử tự động kiểu kiểm tra image build đã được cài đặt đúng và man có cho ra đầu ra như mong đợi hay không
  • Tôi nghĩ để xác định man có kết thúc đúng hay không thì cứ tin vào mã thoát là được
    Đánh giá dựa trên độ dài của stderr thì lúc nào cũng mong manh