2 Punkte von GN⁺ 2024-10-05 | 3 Kommentare | Auf WhatsApp teilen
  • Der Grund, warum ein automatisierter Test nur um 00:30 fehlschlug, war, dass man -w unerwartet die stderr-Zeichenkette gimme gimme gimme zusätzlich ausgab
  • Diese Zeichenkette war ein Easter Egg von man und erschien, wenn das Programm ohne Manual-Seite oder mit -w ausgeführt wurde und die lokale Zeit 00:30 war
  • Die Formulierung stammt aus ABBAs „Gimme! Gimme! Gimme! (A Man After Midnight)“, und ein Tweet-Witz aus dem Jahr 2011 wurde in den man-db-Code übernommen
  • man -w gab den manpath aus und lieferte auch den Exit-Code 0, sodass es in der Automatisierung verwendet werden konnte, aber das Easter Egg konnte das Parsen der Ausgabe stören
  • man-db wurde zunächst so korrigiert, dass es bei man -w nicht mehr ausgelöst wurde, und später wurde beschlossen, das Easter Egg in man-db 2.8.0 vollständig zu entfernen

Ein Test, der nur um 00:30 fehlschlug

  • Ein automatisierter Test funktionierte die meiste Zeit normal, schlug aber nur dann fehl, wenn er um 00:30 lief
  • Die direkte Ursache war, dass zu stderr eine unerwartete Zeichenkette hinzugefügt wurde
gimme gimme gimme
  • Der im Test verwendete Befehl war man -w und diente dazu, den aktuellen manpath zu ermitteln

Das Easter Egg in man

  • Die problematische Zeichenkette war ein Easter Egg im man-Befehl
  • Es wurde unter folgenden Bedingungen ausgelöst
    • man wird ohne Angabe einer Manual-Seite ausgeführt
    • oder man -w wird ausgeführt
    • die lokale Zeit ist 00:30
  • Wenn die Bedingungen erfüllt waren, wurde gimme gimme gimme auf stderr ausgegeben
# date +%T -s "00:30:00"
00:30:00


# man -w
gimme gimme gimme
/usr/local/share/man:/usr/share/man:/usr/man
  • Auch in diesem Fall blieb der Exit-Code bei 0

Das ursprünglich erwartete Verhalten

  • Die normale Ausgabe von man -w besteht nur aus dem Rückgabewert des Suchpfads für Manual-Seiten
# man -w
/usr/local/share/man:/usr/share/man:/usr/man


# echo $?
0
  • Wenn man ohne Seite ausgeführt wird, ist das erwartete Verhalten, nach der gewünschten Manual-Seite zu fragen und den Exit-Code 1 zurückzugeben
# man
What manual page do you want?


# echo $?
1
  • Da man -w den Suchpfad ausgibt, konnte es zur Überprüfung installierter Manual-Seiten oder als Bestandteil von Testautomatisierung verwendet werden

Code und Reichweite über Distributionen hinweg

  • Die betreffende Zeichenkette wurde auf RHEL, OpenSUSE, Fedora, Debian und anderen Distributionen gefunden und war kein Verhalten nur einer bestimmten Distribution
  • Die Existenz der Zeichenkette ließ sich prüfen, indem man sie im Binärprogramm mit grep suchte
  • Die Ausgabe wurde durch Code in src/man.c von man-db erzeugt
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");

Eine Zeichenkette aus einem ABBA-Song und einem Tweet

  • gimme gimme gimme stammt aus ABBAs „Gimme! Gimme! Gimme! (A Man After Midnight)
  • Marnanel Thurman schlug 2011 in einem Tweet scherzhaft vor, dass man, wenn es um 00:01 ausgeführt wird, gimme gimme gimme ausgeben sollte
  • Der man-Maintainer übernahm diesen Vorschlag tatsächlich in den Code
  • Laut ergänzenden Kommentaren wurde das Easter Egg im ersten Commit um 00:01 ausgelöst und später mit einer Commit-Nachricht „half past twelve“ auf 00:30 geändert

Korrektur und Entfernung

  • Der man-db-Maintainer Colin Watson korrigierte das Problem zunächst mit Commit 84bde8, sodass dieses Easter Egg bei man -w nicht mehr ausgelöst wurde
  • Danach wandte Colin Watson einen Commit zur vollständigen Entfernung des Easter Eggs an
  • Das entfernte Easter Egg sollte mit dem geplanten man-db 2.8.0 verschwinden
  • Der Maintainer entschied, dass das Easter Egg zwar einigen Leuten ein Lächeln entlockt hatte, für andere aber lästig war, und dass sechs Jahre lang genug seien

3 Kommentare

 
tribela 2024-10-07

Wenn man solche Easter Eggs einbaut, ist es auch eine gute Methode, einmal zu prüfen, ob die Standard-Ein-/Ausgabe ein TTY ist. In einem Shell-Skript kann man das mit [[ -t 1]] überprüfen.

 
y15un 2024-10-05

man wurde wohl als „männlich“ übersetzt, haha.

 
GN⁺ 2024-10-05
Meinungen auf Hacker News
  • Früher, bevor Telemedizin so verbreitet war wie heute, baute ich eine Telemedizin-Webapp. Patienten füllten online einen Fragebogen aus, und Ärzte konnten die Antworten einsehen.
    Beim Onboarding verschiedener Fachrichtungen gab es eine ziemlich leistungsfähige Logik, die bedingt steuerte, ob Fragen angezeigt wurden. Als ich an einer neuen Funktion für eine psychiatrische Klinik arbeitete und eine Frage, die sichtbar sein sollte, nicht erschien, packte ich beim Debuggen neben die Frage jede Menge unsinnige und leicht wütende Debug-Texte.
    Ich dachte, ich hätte das Problem behoben und aufgeräumt, ließ aber bei einer bestimmten Kombination von Antworten einen Text übrig, der in großen roten Buchstaben I SEE YOU!!! anzeigte. Den entdeckte dann ein Patient, der den Paranoia-Evaluationsfragebogen der neu eröffneten psychiatrischen Klinik ausfüllte.
    Seitdem verwende ich für Debug-Markierungen Dinge wie aaa oder 111.

    • Bei Google war vorgesehen, Debug-Strings mit DO NOT SUBMIT zu versehen, und nachdem ein Debug-String in die Produktion gelangt war, wurde ein Bot hinzugefügt, der darauf prüfte.
      Ich erinnere mich, dass das nach dem legendären WD-Vorfall war, bei dem „western digital“ im Testcode zu „woodly doodly“ geändert und dann versehentlich ausgerollt wurde.
    • Etwas Ähnliches habe ich früher einmal gemacht, als ich für eine Glücksspielseite eine Funktion baute, mit der Leute Wetten massenhaft über spezielle Dateien hochladen konnten.
      Während der Entwicklung brach es nur in einer sehr speziellen Situation, und es sah nach einer seltsamen Bedingung aus, die nur für die lokale Entwicklungsumgebung galt. Also fügte ich eine Fehlermeldung wie „watch and amaze while the application eats itself!“ ein. Der Spruch war von einem Fehler inspiriert, den ich ursprünglich im Discworld-Spiel für PlayStation gesehen hatte.
      Als es dann in die Produktion ging, stellte sich heraus, dass die Bedingung, die den Fehler auslöste, deutlich weniger speziell war als gedacht. Der Kundensupport war durch Hunderte Anrufe von Leuten lahmgelegt, die dachten, ihr Geld sei verschwunden. Die Nutzer dieser Funktion waren High Roller, die große Summen setzten, also war das Management ganz und gar nicht begeistert.
      Zum Glück wurde ich nicht gefeuert und wir behoben es schnell, aber es fühlte sich an, als läge die Klinge ziemlich nah am Hals. In einer meiner ersten Stellen vor fast 20 Jahren habe ich in jener Woche eine wertvolle Lektion gründlich gelernt.
    • In dieser Datei gab es einen Kommentar, den ich lange drin gelassen hatte, aber der Projektlead war ziemlich professionell und löschte ihn. Der Kommentar lautete # MULTIPASS!.
      https://github.com/workarea-commerce/workarea/blob/master/co...
      Der Kontext ist: The 5th Element ist ein großartiger Film, der Hund meiner Schwester hieß Leeloo Dallas Multipass und war mein Lieblingshund, und ich war der Entwickler, der die Suchquery-Funktion ProductMultipass ursprünglich gebaut hat.
      Ich habe auch gelernt, dass lustige Kommentare andere Entwickler dazu bringen, ein Produkt mehr zu mögen.
    • Als Debug-Markierung verwende ich normalerweise meine Initialen zusammen mit DEBUG.
      So ist es vor einem Commit leicht mit grep zu finden, und falls es doch in die Produktion gerät, ist es kein völlig unerklärlicher String.
    • Ich habe ganz sicher schon Debug-Meldungen committet, und ich vermute, den meisten, die Code schreiben, ist das irgendwann einmal passiert.
      Zum Glück war es nichts allzu Peinliches. Heutzutage schaue ich mir als letzte Kontrolle vor Commit und Push immer git diff an und suche nach print oder ähnlichen Ausgaben der jeweiligen Sprache.
      Ein Freund aus der Highschool hatte die Angewohnheit, Entwürfe für Hausarbeiten mit unpassenden Titeln zu versehen. Beim gegenseitigen Korrekturlesen war das lustig, aber einmal vergaß er schließlich, den Titel zurückzuändern. Als die Lehrerin im Englischunterricht herumging, um die Arbeiten einzusammeln, sah mein Freund auf sein Blatt, sprang plötzlich auf, sagte, er müsse auf die Toilette, rannte in den Computerraum und druckte eine neue Fassung aus, bei der oben kein 24-Punkt-Schimpfwort stand. Ich wäre fast vor Lachen gestorben.
  • Wenn Software kostenlos ist und die Maintainer nicht bezahlt werden, halte ich ein paar Easter Eggs für einen kleinen Preis.
    Natürlich wurde Colin bezahlt, aber nicht hauptsächlich für die Wartung von man.
    In einer Firma, bei der ich einmal gearbeitet habe, fügte ein Entwickler in die Nutzungsbedingungen einen Satz ein, wonach der Nutzer seine Seele an das Unternehmen abtritt. Die Absicht war zu sehen, ob die Geschäftsführung oder die Rechtsabteilung die Bedingungen wie versprochen prüften. Taten sie nicht, und viele Seelen wurden eingefangen.

    • Dann könnte womöglich die gesamte Nutzungsvereinbarung ungültig werden.
  • Programmieren sollte Spaß machen, und Code zu schreiben sollte ebenfalls Spaß machen. Ich finde, diese Leute haben es richtig gemacht.
    Die Vorstellung, Open Source müsse kalt und ernst sein, ist nur durch den Einfluss von Unternehmen entstanden. Wenn ich mit meinem Freund ein Programm bauen würde, würde ich vermutlich überall Easter Eggs einbauen, um daran zu erinnern, dass auf der anderen Seite ein Mensch sitzt.

    • Da sie versteckt sind, werden die meisten Leute diese Easter Eggs nie antreffen.
      Wer sie antrifft, stolpert wie im Ausgangsbeitrag zufällig darüber, und dort ist die Continuous-Integration-Pipeline kaputtgegangen. Als Werkzeug, um daran zu erinnern, dass „auf der anderen Seite ein Mensch sitzt“, halte ich Easter Eggs für eher ungeeignet.
      Zumindest außerhalb von Entertainment-Software.
    • Es gibt kaum etwas, das so unterhaltsam und befriedigend ist wie ein gut verstecktes Easter Egg.
      Besonders dann, wenn das Arbeitsobjekt von bürokratischen Abläufen umgeben ist. Mein persönlicher Favorit ist ein Rickroll, den ich vor ein paar Jahren in den Quellcode einer Regierungsanwendung geschmuggelt habe, die ich als Berater reparierte. Nur Entwickler, die an einem ganz bestimmten Subsystem arbeiten, können ihn finden, aber wenn sie ihn entdecken, ist aus dem Kontext klar, warum er dort ist.
    • Ein Easter Egg, das für den einen lustig ist, kann für jemand anderen in seinem Workflow ein Trigger für nichtdeterministisches Fehlverhalten mit realen Folgen sein.
      Das ist ein weiterer Grund, warum es schwer ist, Software zu vertrauen, die in lebenssicherheitsrelevanten oder missionskritischen Anwendungen aus mehreren Komponenten mit unterschiedlichen Engineering-Prozessen integriert wurde.
  • Inzwischen ist es nicht mehr enthalten.
    Colin Watson, der Entwickler von man-db, fand, es sei ausreichend lustig gewesen und die Geschichte werde nicht vergessen werden, und hat das Easter Egg vollständig entfernt.
    https://git.savannah.gnu.org/cgit/man-db.git/commit/?id=b225...

    • Ich habe in der Diskussion zu diesem Issue einmal einen schönen Kommentar gelesen, den ich jetzt nicht mehr finden kann.
      Darin hieß es, man solle solche Easter Eggs drinlassen, weil gerade solche Dinge am Ende Menschen von Maschinen unterscheiden.
    • Ich habe es gerade auf einem alten Raspberry Pi ausprobiert, dort ist es noch vorhanden. Er basiert auf Debian 9 Stretch.
  • Verwandte Beiträge:
    Why does man print “gimme gimme gimme” at 00:30? (2017) - https://news.ycombinator.com/item?id=27994194 - Juli 2021, 211 Kommentare
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15747313 - November 2017, 159 Kommentare
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15746972 - November 2017, 1 Kommentar
    Why does man print “gimme gimme gimme” at 00:30? - https://news.ycombinator.com/item?id=15742221 - November 2017, 1 Kommentar

  • Eine lustige Idee, aber sie gehört nicht in den normalen Ausführungspfad. Das schadet den Nutzern.
    Wie der Autor des Originalbeitrags sagte, wäre man -abba besser gewesen.

    • Der ersten Antwort zufolge sollte es ursprünglich nur in einer Fehlersituation ausgelöst werden, also wenn keine Seite angegeben wurde.
      Durch einen Fehler wurde es aber auch ausgelöst, wenn man die Manpage statt als Seitennamen über das Flag --path angegeben hatte.
    • $ man --abba --format=json
      ["gimme", "gimme", "gimme"]
    • Wurde entfernt. Siehe: https://news.ycombinator.com/item?id=41738239
  • Dieses Update hat meinen Workflow kaputtgemacht.

    • Dieses Update hat meinen Workflow repariert. Ich brauchte man nach Mitternacht.
  • Beim Abschaffen des alten Telefonsystems habe ich in der Firma FreePBX installiert.
    Weil es nicht viele Nebenstellen gab, nutzten wir 1xx, 2xx und 3xx für verschiedene Arten von Nebenstellen und hatten trotzdem noch viele Nummern übrig. Also baute ich ein kleines Easter Egg ein: Wenn jemand die Nebenstelle 666 anrief, wurde Vincent Prices gruseliges Lachen am Ende von Michael Jacksons Thriller abgespielt.
    Ein oder zwei Jahre später schrieb mir ein Kollege früh am Morgen eine Nachricht, das Telefon sei wohl gehackt worden; egal wohin er anrufe, höre er eine gruselige Stimme. Beim Nachsehen stellte sich heraus, dass etwas schiefgelaufen war und alle Anrufe an die zuletzt hinzugefügte Nebenstelle weitergeleitet wurden: 666.
    Natürlich fanden die Leute dieses Easter Egg nicht lustig und fühlten sich von dem Lachen beleidigt.

  • Ich frage mich, ob es eine Hypothese dazu gibt, warum es einen Test gab, der man ohne Argumente aufruft.
    Ging es nur darum zu prüfen, ob man installiert ist? Selbst dann würde man den Befehl vermutlich so testen, wie er üblicherweise verwendet wird.

    • Wenn man die Antworten liest, scheint das Easter Egg versehentlich auch dann ausgelöst worden zu sein, wenn die zu ladende Seite per --path übergeben wurde.
      Das wurde später behoben, und noch später wurde das Easter Egg komplett entfernt.
    • Die Stack-Overflow-Frage selbst wirkte wie eine konstruierte Frage, damit jemand anderes seine Geschichte öffentlich erzählen konnte.
    • In den Kommentaren zur verlinkten Stack-Overflow-Frage wurde das ausführlich behandelt; kurz gesagt: Man wollte manpath haben: man -w
    • Es könnte auch ein automatisierter Test gewesen sein, der prüft, ob das Build-Image korrekt installiert wurde und man die erwartete Ausgabe liefert.
  • Um festzustellen, ob man korrekt beendet wurde, sollte man sich meiner Meinung nach auf den Exit-Code verlassen.
    Das anhand der Länge von stderr zu beurteilen, ist immer fragil.