- 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
- Vì
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
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]].manđã được dịch là nam giới rồi nhỉ hahaBì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
aaahoặc111Hì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
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 đó
# 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
ProductMultipassTô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
Như vậy sẽ dễ tìm bằng
greptrướ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ểmMay là nội dung không quá xấu hổ, còn bây giờ tôi luôn xem
git diffnhư bước kiểm tra cuối trước khi commit và push, đồng thời tìm các lệnhprinthoặ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ữ
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
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í
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
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 egghttps://git.savannah.gnu.org/cgit/man-db.git/commit/?id=b225...
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
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 -abbathì đã tốt hơnNhưng do nhầm lẫn, nó cũng kích hoạt cả khi chỉ định man page bằng cờ
--paththay vì tên trang$ man --abba --format=json["gimme", "gimme", "gimme"]Bản cập nhật này đã làm hỏng quy trình làm việc của tôi
mansau nửa đêmKhi 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
manmà 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--pathSau đó phần này đã được sửa, và về sau toàn bộ Easter egg cũng bị loại bỏ
man -wmancó cho ra đầu ra như mong đợi hay khôngTôi nghĩ để xác định
mancó 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
stderrthì lúc nào cũng mong manh