Login-Aufforderung des Simulators

Nein, ich bin nicht auf die Tastatur gefallen. Ich spiele zur Zeit mit alten Versionen von Unix. Mit sehr alten Versionen…

Disclaimer: Diesen Artikel habe ich nicht mit KI geschrieben, genau wie jeder andere in diesem Blog ist er von Hand formuliert. Holprig wie immer. Nur der Codeschnipsel am Ende ist synthetisch. Ich nutze hier aber tatsächlich Ausgaben von KI-Systemen. Erst um mich darüber lustig zu machen, am Ende hat eine KI aber offenbar doch meine Frage richtig und zufriedenstellend beantwortet. Soweit ich das beurteilen kann. Urteilt selbst.

Vor mehr als zehn Jahren war ich vom PiDP-8/I fasziniert, einem Gehäuse in dem sich ein Raspberry wie eine PDP-8 bedienen lässt, also wie ein Computer aus den 1960er Jahren. Zur Zeit denke ich ernsthaft über eine PiDP-11 nach, weil ich mit der PDP-11 tatsächlich deutlich mehr verbinde — unter anderem weil das die Wiege von Unix gewesen ist. Die Software für das Ding kann man freundlicherweise auch ohne die Hardware ausprobieren, und genau das mache ich mit wachsender Begeisterung.

Wir befinden uns also in einem 1st Edition Unix, auf der Rekonstruktion eines Systems von 1972.

Vor knapp 25 Jahren war ich eine Weile beruflich irgendwo in München, in einem Projekt mit mehreren Kollegen die deutlich mehr Unix-Erfahrung hatten als ich. Einer der Kollegen hat erzählt dass er in seiner Anfangszeit Wissen aufgebaut hat indem er sich die Dateien in /bin und /usr/bin angesehen, und dann jeweils die Man-Pages studiert hat. Gute Idee für einen ersten Überblick.

Mein Oldtimer hat keine Man-Pages. Die gab es zwar schon 1971, aber hier sind keine installiert.

Alle Binaries die mit c anfangen

Die meisten Kommandos konnte ich auch so identifizieren. Am Rande: achtet mal auf die Größen der Dateien. Auf meinem Linux umfasst /bin/cat etwa 50kB, /bin/chmod etwa 70kB. :-)

Die 76 Bytes von /bin/chball entzogen sich aber meiner Kenntnis.

In der Maschine gibt es keine Doku. Ich habe mir diverse Handbücher aus den 1970ern angesehen. Die sind wirklich gut, aber das Kommando wurde da nicht beschrieben. Im Git-Repo gibt es eine Datei in der viele Binaries kommentiert werden, aber auch da steht zu „chball“ nur „no idea“. Auch ansonsten haben meine Web-Recherchen nicht wirklich zu Ergebnissen geführt. Bis mir DuckDuckGo irgendwelche KI-Ergebnisse gegeben hat. Verzweiflungstat, vermutlich. Ebenso verzweifelt habe ich dann versucht aus diesem Ding Infos rauszupopeln.

„Changing or managing ballistics“?!?

Ich habe Ergebnisse bekommen. Und was für welche.

Die erste Idee war, dass /bin/chball gebraucht wurde wenn der Kugelkopf im Terminal getauscht wurde. Auf dem bekannten Foto von Dennis Ritchie und Ken Thompson an einer PDP-11 sind auch zwei Teletype 33 zu sehen, und die hatten Kugelköpfe. Aber der Tausch ist eher ein mechanischer Vorgang, wozu braucht man so ein Kommando? Die KI hat mir auch Beispielaufrufe gezeigt, die haben aber nur zu einer Fehlermeldung geführt. Und zu der Zeit war ein einfaches, vorwurfsvoll-nachdrückliches „?“ offenbar eine hinreichende Fehlermeldung.

Einen Tag später habe ich nochmal mein Glück versucht. Diesmal gab es eine genauso plausible, wenn auch komplett andere Erklärung. Das Kommando stünde für „change block allocation“. Das alte Dateisystem verfügt noch nicht über Inodes, deshalb muss man mit dem Kommando Platz im Dateisystem allozieren wenn die Datei größer wird.

KI-Halluzination — plausibel klingender Blödsinn

Nanu? OK, neues Browserfenster, noch ein Versuch. Diesmal konnte man mit dem Kommando das ball-Bit von Dateien umschalten. Spannend, davon hatte ich noch nie gehört. Sonst aber auch niemand. Weil es einfach Quatsch ist. Und genau wie die Block-Allozierung nur zur gewohnten Fehlermeldung geführt hat.

Ich hatte also drei völlig unterschiedliche Erklärungen. Alle plausibel, alle selbstsicher formuliert, alle mit Anwendungsbeispielen, und alle führten nur zu einer Fehlermeldung. Völlig wertlos, also. :-(

Am nächsten Tag habe ich das einem Freund und Kollegen erzählt. Mit einer Prise Sarkasmus, und das hat ihn vermutlich getriggert. Er kennt sich deutlich besser mit LLMs aus als ich, und er hat Abends ChatGPT zur Rede gestellt. Und hatte 20 Minuten später ein umfassendes Dossier.

Er hat erst allgemein nach einer Erklärung gefragt. ChatGPT hatte auch die Info dass das was mit dem Kugelkopf zu tun hat, und hat vorgeschlagen das Binary zu untersuchen. Es hat sich das Festplatten-Image hochladen lassen in dem das Binary enthalten ist, hat das Binary extrahiert und dann in PDP-11 Syntax disassembliert. Den Assembler-Code hat es dann an den verwendeten Kernel gehalten um zu sehen welche Bedeutung das gesetzte Bit hat, und hat dann lesbaren C-Pseudocode generiert:

Das Kommando müsste also als Parameter ein einfaches „e“ oder ein „c“ bekommen, daraufhin die Settings des aktuellen Terminals ändern. Ähnlich wie man das unter Linux mit stty macht. Und richtig genug: wenn man es in der simulierten Maschine so aufruft gibt es keine Fehlermeldung. Heureka!

Testen kann ich die Funktion allerdings nicht, dafür fehlt mir ein mechanisches Terminal — und mehrere Kugelköpfe. :-)

Das LLM hat noch ein paar Hintergrundinformationen gebracht, sogar Bilder von unterschiedlichen Kugelköpfen. Ich muss zugeben: alles was da rausgekommen ist sehe ich als logisch und plausibel an. Ich bin wirklich beeindruckt. Kritisch sehe ich das ganze immer noch, aber aus anderen Gründen. Das Ergebnis überzeugt, fast alles andere an der Technik sehe ich als fragwürdig an.

Das Kommando /bin/chball wird also tatsächlich nach dem Tausch des Kugelkopfes im Teletype gebraucht. Der Parameter e wird vermutlich gebraucht wenn man eine Kugel mit EBCDIC-Zeichensatz einbaut, mit dem Parameter c schaltet man wieder auf Correspondence-Zeichensatz um.

Ich musste breit grinsen als ich diesen Text sah:

„I am a Unix Creationist. I believe the world was created on January 1, 1970 and as prophesized, will end on January 19, 2038″

Noch breiter wurde das Grinsen in den Kommentaren. Interessant dass die am lautesten schreien die am wenigsten verstehen was gesagt wurde. :-D

Heute habe ich mich (unter anderem) mit einem Problem beschäftigt das auf den ersten Blick trivial aussieht. Ich zumindest habe bislang keine Lösung gefunden die mir wirklich gefällt. Mal sehen ob was dabei rauskommt wenn ich das hier ‚crowdsource’… :-)

Aufgabenstellung: Zähle, wie viele Prozesse eines bestimmten Programmes schon länger als 30 Minuten laufen.

Klingt einfach, oder?

Die Ausgaben von ps zu parsen erscheint mir dabei aber zu fehleranfällig. Da müsste man zu viel berücksichtigen: Prozesse die vielleicht länger als einen Tag laufen, Prozesse die über Mitternacht gelaufen sind… ich habe nicht getestet wie es aussieht wenn man an der Zeitzone rumspielt… Nein, das kann nicht der richtige Ansatz sein.

Meine erste echte Lösung sieht zwar hässlich originell aus, funktionierte aber im Test (zu Demozwecken suche ich mal nach meinem Firefox):

echo | killall -i --older-than 30m firefox 2> /dev/null | tr -cd '?' | wc -c

Mit -i ist killall ‚interaktiv‘, fragt also zu jedem gefundenen Prozess freundlich nach ob es zuschlagen soll. Mit dem reingepipten echo beantwortet es sich diese Frage immer negativ. Der Rest der Zeile zählt im Prinzip wie oft killall gefragt hat ob es töten soll.

Blöd ist, dass die auf einem etwas älteren RHEL laufen soll. Anders als bei Ubuntu kennt killall da die Option –older-than noch nicht.

Der zweite Lösungsansatz funktioniert leider nur auf den ersten Blick, dafür aber auch auf dem alten Red Hat:

find /proc/[0-9]* -maxdepth 1 -name status -mmin +30 | xargs egrep "^Name:\sfirefox$" | wc -l

Ich suche also alle Prozesse die schon länger als 30 Minuten laufen, und suche in deren status-Datei nach dem Namen meines Prozesses. Die Ergebnisse werden dann wieder gezählt. Alternativ könnte man statt in der status- auch in der cmdline-Datei suchen, in meinem echten Einsatz übersehe ich damit dann auch Zombies (die werden separat betrachtet). Leider funktioniert dieser Ansatz nicht wirklich zuverlässig. Es sieht so aus als ob der Kernel den Dateien im Proc-Verzeichnis bisweilen einen neuen Timestamp gibt — obwohl der Prozess nicht gestartet oder beendet wurde. Ein Schuss in den Ofen, also. :-(

Wie macht man sowas? Ich meine, wenn man eine zuverlässige Lösung mit Bordmitteln haben will? Gibt es da ein passendes Tool das ich noch nicht kenne? Oder hilfreiche Optionen für gängige Tools? Wenn ich die Suchmaschine meiner Wahl frage finde ich eine Menge Lösungen, aber die sind entweder auch wackelig, oder sie bestehen darauf direkt alles zu töten…

Kein guter Monat in der IT. Letztes Wochenende ist Dennis Ritchie gestorben. :-(

Er war Miterfinder der Programmiersprache C und des Betriebssystems Unix, und somit vermutlich einer der absolut einflussreichsten Köpfe der Branche. Auch nach mehr als 40 Jahren haben seine Ideen immer noch einen wirklich prägenden Einfluss auf einen Bereich der kaum schnellebiger sein könnte.

Unix und seine Folgen

Unix und seine Folgen

Wer der Ansicht ist damit nichts zu tun zu haben — nicht jeder hat das Privileg mit einem wirklichen Unix arbeiten zu dürfen — mag sich folgendes verdeutlichen:

  • Linux basiert auf den Ideen von Unix.
  • Android enthält einen Linux-Kern, und somit indirekt die Ideen von Dennis Ritchie.
  • Der Kern von Apples MacOS stammt von BSD ab, also von einem echten Unix.
  • Apples iPod, iPhone und iPad enthalten meines Wissens auch einen BSD-basierten Kern.
  • Sogar Windows versucht an einigen Stellen sich an Posix-Standards zu halten, also an die Grundlage von Unix.

Unix is simple and coherent, but it takes a genius ” or at any rate a programmer ” to understand and appreciate the simplicity. (Dennis Ritchie)

Und jedes Mal wenn ich beobachte dass andere Systeme wieder irgendwelche Unix-ähnlichen Features übernommen habe denke ich dan dieses Zitat:

Those who don’t understand Unix are condemned to reinvent it, poorly. (Henry Spencer, Autor von regex)

Ach ja, Ritchie hatte offenbar auch einen ‚besonderen‘ Sinn für Humor:

We stopped when we got a clean compile on the following syntax:

for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);

At one time, we thought of selling this to the Soviets to set their computer science progress back 20 or more years.

So zu lesen im Geständnis dass die Idee mit C und Unix eigentlich nur ein Gag gewesen sein sollte — im Jahr 2001. :-D

Ich sehe in Sachen Computer gerne mal über den Tellerrand oder in die Geschichte. Einen PC zu programmieren ist ja schon spannend, eigene Programme auf einem Mikrocontroller oder einem HP-42S laufen zu lassen ist aber ein echtes Abenteuer. Sich da rein zu denken ist wie das Eintauchen in eine andere Welt.
Eine Plattform mit der ich immer schon mal spielen wollte ist die PDP-11. Ein echtes Stück Technikgeschichte. Dementsprechend begeistert sehe ich mir gerade einen Emulator an. Geschrieben in… Javascript! In dem Emulator kann man ein Unix starten und benutzen. Emuliert wird auf Hardware-Ebene, mit dem Ding sollte sich also praktisch alles machen lassen was man auch mit der originalen Maschine machen konnte. Wenn auch die Haptik natürlich fehlt…
Ein paar Widrigkeiten der Emulation klärt die FAQ, leider weiß ich aber noch nicht warum alles elendig langsam ist. Klar fühlt sich Technik aus den 70ern anders an als aktuelle, trotzdem habe ich das Gefühl dass das entweder an meiner Hardware oder — wahrscheinlicher — an meiner dünnen Leitung liegt. Ist das überall so langsam?

Dass man Passworte und ähnlich vertrauliche Sachen nicht in Kommandozeilen verwenden sollte ist mir klar. Jeder der auf dem gleichen System angemeldet ist kann sich mittels ‚ps auxwww‘ den vollständigen Aufruf anzeigen lassen, einschließlich womöglich benutzter Passworte.

Bisher hätte ich in meinem jugendlichen Leichtsinn aber keine Bedenken gehabt, solche Daten in Umgebungsvariablen zu hinterlegen. Klar, irgendwo unter /proc findet man die soweit ich weiß auch wieder. Aber nur wenn man root ist, oder wenn man Spaß daran hat, seine eigenen Prozesse zu bespitzeln. Fremde Prozesse kann man so nicht einsehen.

Es geht aber auch anders: mit ‚ps auxwwwe‘ — das ‚e‘ steht offenbar für ‚Environment‘ — stehen auch Umgebungsvariablen in der Prozessliste. Für alle Benutzer auf dem gleichen System einsehbar, ohne dass die über besondere Rechte verfügen müssen.

Man lernt nie aus… Und nachdem ich das jetzt weiß werde ich erstmal gründlich in mich gehen um rauszufinden wo ich eventuell solche Leichen im Keller habe… :-(