- Julia Evans’ Strange-Loop-Keynote behandelt, warum Technologien wie DNS, Bash, HTTP und SQL, die auf den ersten Blick „grundlegend“ wirken, trotzdem lange zum Lernen brauchen, und wie man die Lernhürde senken kann
- Bash ist schwierig, weil es viele kleine Ausnahmen und Fallstricke gibt, etwa dass
set -ebei Funktionsaufrufen innerhalb einer||-Bedingung deaktiviert wird, und weil viele Leute Bash nur gelegentlich verwenden und sich Details daher schwer exakt merken lassen - Bei HTTP und SQL verbirgt sich hinter einer einfachen Oberfläche eine Browser-Implementierung mit 20 Millionen Zeilen Code, zahlreiche Header und Flags sowie bei SQL der Unterschied zwischen Schreibreihenfolge und Ausführungsreihenfolge, was den Lernaufwand erhöht
- Bei DNS sind Bibliotheken, Caches und die Kommunikation mit autoritativen Nameservern für Nutzer oft unsichtbar, und auch die Ausgabe von
digist komplex; deshalb sind Werkzeuge und Demos, die verborgenes Verhalten sichtbar machen, wichtig - Gute Lernunterstützung bedeutet, Werkzeuge und Referenzen zu teilen, große Listen auf kleine, tatsächlich genutzte Listen zu reduzieren, zu erklären, was der Computer in zeitlicher Reihenfolge tut, und auch Fehlgeschichten sowie Bug-Protokolle weiterzugeben
Warum „grundlegende“ Technologien trotzdem lange zum Lernen brauchen
- Die Strange-Loop-Keynote Making Hard Things Easy behandelt, wie sich schwer zu lernende Technologien leichter machen lassen
- Ausgangspunkt war DNS
- Das Finden der IP-Adresse eines Domainnamens wirkt einfach, aber die Vortragende sagt, dass sie selbst sieben Jahre nach dem Einstieg in DNS beim Einrichten von Websites noch Probleme hatte und insgesamt etwa zehn Jahre brauchte
- Auch Freunde hatten immer wieder dieselben Probleme, und viele nahmen das als persönliches Versagen wahr, nach dem Motto: „Das müsste ich doch längst verstanden haben“
- Um solche Themen leichter zugänglich aufzuschreiben, gründete die Vortragende den kleinen Verlag Wizard Zines und nutzt Bash, HTTP, SQL und DNS als Beispiele
Bash: Schwer merkbare Ausnahmen sollte das Werkzeug übernehmen
- Bash ist eine Programmiersprache, gehört für die Vortragende aber auch zu den Sprachen mit besonders seltsamem Verhalten
- Im Beispielskript schlägt
mv ./*.txt /tmmppfehl, aber Bash stoppt standardmäßig nicht und führt trotzdemecho "success!"aus- Mit
set -ekann man Bash bei Fehlern abbrechen lassen - Wird eine Funktion aber innerhalb einer
||-Bedingung wief || echo "failed!"aufgerufen, wirdset -einnerhalb der Funktion global deaktiviert, sodass wiedersuccessausgegeben wird - Dieses Verhalten ist kein Bash-Bug, sondern dokumentiert
- Mit
- Ein Grund, warum Bash schwierig ist: Viele Leute schreiben nur alle sechs Monate einmal ein Bash-Skript und schauen es danach nie wieder an
- Wenn ein selten genutztes System voller Spezialwissen und Fallstricke ist, wird korrekte Nutzung schwierig
- Die Reaktion „Niemand kann Bash“ stimmt so nicht
- Viele Leute benutzen Bash und bekommen damit oft genug Dinge erledigt, auch wenn nicht alles perfekt ist
- Das Ziel ist, Menschen nicht vor einem überwältigenden Haufen Fallstricke stehen zu lassen, sondern sie in einen Zustand zu bringen, in dem sie es „meistens richtig“ verwenden können
- ShellCheck ist ein Werkzeug, das sich schwer merkbare Bash-Fallstricke für Menschen merkt und davor warnt
shellcheck -o all bad-again.shmeldet mit der WarnungSC2310, dassset -ebei einer Funktion deaktiviert wird, die innerhalb einer||-Bedingung aufgerufen wurde- Diese Prüfung erscheint nur mit
-o all - Solche Werkzeuge verlagern Spezialwissen auf den Computer und senken damit die kognitive Last
Fehlgeschichten helfen bei Entscheidungen mehr als „Best Practices“
- Auch ohne eigene Tools zu bauen ist es wichtig, nützliche Werkzeuge, die man bereits verwendet, an Freunde oder Kolleginnen und Kollegen weiterzugeben
- Die Vortragende sagt, dass sie ShellCheck erst spät kennengelernt habe und verärgert gewesen sei, so lange geglaubt zu haben, sie müsse sich all das im Kopf merken
- Das Teilen von Fallstricken und Fehlgeschichten ist fast schon ein Dienst an der Community
- Das Beispiel mit dem deaktivierten
set -ein Bash stammt aus einer Erfahrung, von der sie erst einige Wochen zuvor durch ihren Freund Jesse erfahren hatte - Wer die Fehlgeschichte anderer kennt, kann dasselbe Problem vermeiden, ohne es selbst erlebt zu haben
- Das Beispiel mit dem deaktivierten
- Starke Aussagen wie „Niemand sollte Bash verwenden“ sind weniger nützlich als konkrete Geschichten darüber, welche Probleme Bash tatsächlich verursacht hat
- Wer dieselbe Geschichte hört, könnte sich dafür entscheiden, ShellCheck zu verwenden und einfache Bash-Skripte weiter zu pflegen
- Jemand anderes könnte daraus schließen, Bash lieber ganz zu vermeiden
- Unterschiedliche Reaktionen auf dasselbe Beispiel sind in Ordnung
HTTP: Man muss es vor dem Hintergrund eines Browsers mit 20 Millionen Zeilen Code verstehen
- Eine HTTP-Antwort kann wie eine einfache Struktur aus Statuscode, Headern und Body wirken
- Doch die Frage „Warum muss ich diesen Header setzen?“ führt schnell zum Verhalten des Browsers
- Firefox besteht aus etwa 20 Millionen Zeilen Code
- Browser haben sich seit den 1990er Jahren weiterentwickelt, und auch ihre Sicherheitsmodelle haben sich fortlaufend an Web-Angriffe und Veränderungen angepasst
- Um zu verstehen, warum ein Thema schwierig ist, sollte man prüfen, ob dahinter eine sehr große Codebasis steckt
- Es geht nicht nur um HTTP, sondern auch um CSS, JS und anderes, aber die Komplexität moderner Browser erklärt gut, warum HTTP eine hohe Lernhürde hat
- Große Listen sollte man auf kleine Listen reduzieren, damit sie verständlicher werden
- Die Liste der HTTP-Request-Header umfasst mehr als 43 Einträge, dazu kommen inoffizielle Header
- In ihrem Comic zu HTTP-Request-Headern behandelt die Vortragende die 15 Header, die sie selbst kennt und verwendet
- Die „wichtigsten Header“ sind keine objektive Liste, sondern eine subjektive Liste dessen, was man selbst kennt und nutzt
- Zum Beispiel reicht es oft schon zu wissen, dass man durch Setzen von
Accept-Encodingaufgzipkomprimierte Antworten erhalten kann
- Dasselbe Prinzip lässt sich auf Kommandozeilenwerkzeuge anwenden
- Die Manpage von
grepenthält viele Flags, aber auch nach 20 Jahren Nutzung kennt die Vortragende nicht alle - Für Anfänger ist es hilfreich, wenn Erfahrene sagen: „Ich kenne in diesem System sieben Dinge, und das sind sie“
- Andere Erfahrene könnten wiederum andere sieben Dinge kennen
- Die Manpage von
Referenzen sollten ehrlich widerspiegeln, was man wirklich benutzt
- Für Informationen, die nicht in den Kopf passen, braucht es gute Referenzen
- Die Vortragende sagt, sie habe CSS 20 Jahre lang immer wieder nebenbei gelernt und CSS-Tricks erst in den letzten etwa zwei Jahren entdeckt; hätte sie die Seite früher gekannt, wäre das hilfreich gewesen
- Seit der Übernahme scheint CSS-Tricks zwar seit April keine neuen Artikel mehr zu veröffentlichen, aber die bestehenden Inhalte sind weiterhin nützlich
- Für HTTP nutzt sie oft Mozilla Developer Network
- Als offizielle Referenzen für HTTP gibt es die 2022 veröffentlichten RFC 9110, 9111, 9112, 9113, 9114
- Dort lassen sich Details wie das genaue Verhalten des
Connection-Headers nachschlagen - Die wichtigste Referenz der Vortragenden ist meist MDN, aber sie schätzt, dass die offiziellen RFCs gut strukturiert sind
- Dort lassen sich Details wie das genaue Verhalten des
- Beim Teilen von Referenzen sollte man unterscheiden zwischen dem, was man teilt, weil es gut aussieht, und dem, was man im Alltag tatsächlich verwendet
- Selbst wenn man in der Praxis eine „weniger coole“ Referenz wie w3schools nutzt, ist es wichtig, das ehrlich zu sagen
SQL: In zeitlicher Reihenfolge beschreiben, was der Computer tut
- SQL kann für Einsteiger verwirrend sein, weil die Reihenfolge, in der man eine Query schreibt, nicht der tatsächlichen konzeptionellen Ausführungsreihenfolge entspricht
- Das mentale SQL-Modell der Vortragenden folgt dieser Reihenfolge
FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT
- Reale Datenbanken sind durch Optimierungen komplizierter, aber dieses zeitliche Modell ist in den meisten Situationen nützlich
- Es entspricht fast der Schreibreihenfolge der Query, mit dem Unterschied, dass
SELECTan fünfter Stelle kommt
- Es entspricht fast der Schreibreihenfolge der Query, mit dem Unterschied, dass
- Die Frage „Was macht der Computer tatsächlich zuerst?“ lässt sich auch auf andere Themen anwenden
- Bei CORS kann man die gesamte Kommunikation zwischen Browser und Server in zeitlicher Reihenfolge aufschreiben, um sie zu verstehen
- Als Beispiel dafür nennt die Vortragende ihren CORS-Comic
- Solche zeitlichen Erklärungen wirken einfach, sind in Wahrheit aber schwer und deshalb für Zusammenarbeit wertvoll
- Behind Hello World on Linux beschreibt, was beim Ausführen von „hello world“ unter Linux passiert
- Schon vor zehn Jahren schrieb die Vortragende einen ähnlichen Artikel, aber der Text von 2023 war etwa sechsmal so lang
- Nicht weil Linux komplexer geworden wäre, sondern weil sie 2013 selbst noch viel weniger darüber wusste, was zeitlich nacheinander geschieht
- Auch im Team kann man gemeinsam eine zeitliche Timeline erstellen, was passiert, wenn eine Anfrage an einen API-Endpunkt eingeht, und so das Wissen aller zusammenführen
DNS: Verborgene Systeme müssen sichtbar werden, damit Intuition entsteht
- DNS ist ein System, in dem Browser, Bibliotheksfunktionen zum Senden von DNS-Anfragen, Caches und autoritative Nameserver zusammenarbeiten
- Das Problem ist, dass vieles davon für Nutzer verborgen ist
- Es ist nicht leicht herauszufinden, welcher Bibliothekscode eigentlich die DNS-Anfrage sendet
- Caches lassen sich schwer auf ihre gespeicherten Daten prüfen und stehen nicht unter der Kontrolle der Nutzer
- Auch die Kommunikation zwischen Cache und autoritativem Nameserver ist unsichtbar
- Gemeinsam mit ihrer Freundin Marie hat die Vortragende einen kleinen DNS-Server namens Mess With DNS gebaut
- Nutzer können dort DNS-Records für eine Domain anlegen
- Bei jeder Anfrage eines Resolvers wird angezeigt, welche Nachricht eingegangen ist
- In der Strange-Loop-Demo legte sie für den Namen
strangeloopeinen CNAME-Record an, der auforange.jvns.cazeigt, und sah dann, dass der vom Browser verwendete kanadische DNS-Resolver A- und AAAA-Records anfragte
- Ein weiteres Beispiel für das Sichtbarmachen verborgener Dinge ist float.exposed
- Dort kann man bei einer 32-Bit-Gleitkommazahl Significand und Exponent verändern und sehen, wie sich die nächste Gleitkommazahl und ihre Abstände ändern
- Ein weiterer Grund, warum DNS schwierig ist: Es handelt sich um ein riesiges verteiltes System
- Die Vortragende sagt sinngemäß, dass dabei „mehr als fünf Millionen Computer beteiligt sein könnten“, von denen die meisten außerhalb der eigenen Kontrolle liegen und einige sich anders verhalten können als erwartet
Wenn Werkzeuge selbst zur Lernhürde werden, wie bei der dig-Ausgabe
- Auch die Ausgabe von DNS-Werkzeugen kann die Verwirrung verstärken
dighat das Flag+norecurse- Damit kann man den Resolver anweisen, nur Ergebnisse zurückzugeben, die sich bereits im Cache befinden
dig +norecurse jvns.calässt sich zum Beispiel verwenden, um zu prüfen, ob der Resolver diese Domain in den letzten fünf Minuten zwischengespeichert hat
- Die Ausgabe von
digkann Anfängern den Eindruck vermitteln, DNS selbst sei noch komplizierter, als es ohnehin schon ist- Die Vortragende sieht darin eher die Folge eines relativ willkürlichen Ausgabeformats aus den 1990er Jahren, das sich lange gehalten hat
- „eraser eyes“ bedeutet, bei komplexer Ausgabe alles gedanklich auszublenden, was man gerade nicht braucht, und nur den relevanten Teil zu betrachten
- Im Beispiel achtet sie nur auf den Response-Code
SERVFAIL - Ihrem Verständnis nach bedeutet
SERVFAILin diesem Kontext ungefähr „nicht im Cache vorhanden“
- Im Beispiel achtet sie nur auf den Response-Code
- Wenn man Werkzeuge demonstriert, hilft es beim Lernen, explizit zu sagen, welche Ausgabe oder welches UI man betrachtet und was man ignoriert
dighat eine raue Ausgabe, aber viele Funktionen; es unterstützt+norecurse, ist überall verfügbar und verändert sich seit Langem kaum, was es stabil macht
Rollen, mit denen wir Dinge gemeinsam einfacher machen können
- Die Praxis, Technologien leichter zu machen, lässt sich auch ohne Blog mit Menschen im eigenen Umfeld teilen
- Die von der Vortragenden zusammengefassten Ansätze sind:
- nützliche Werkzeuge teilen
- Referenzen teilen, die man wirklich benutzt
- in zeitlicher Reihenfolge erklären, was auf dem Computer passiert
- große Listen auf kleine Listen reduzieren, die man tatsächlich verwendet
- verborgenes Verhalten sichtbar machen
- verwirrende Werkzeuge vorführen und erklären, worauf man achtet
- Auch die Arten von Menschen, die dabei helfen, sind vielfältig
- Der „mürrische alte Nutzer“ erzählt, was früher schiefgelaufen ist, und spart anderen Mühe
- Der „laute Anfänger“ fragt „Wie funktioniert das?“ und erleichtert damit auch anderen das Nachfragen
- Wenn Senior-Entwickler öffentlich Fragen zu Dingen stellen, die sie nicht wissen, können andere mitlernen, die sonst Angst hätten, unwissend zu wirken
- Der „Bug-Chronist“ hält fest, was passiert ist, damit derselbe Fehler nicht erneut auftritt
- Der „Tool-Bauer“ schreibt Code statt dieselbe Erklärung immer wieder zu geben und macht ein Problem dauerhaft leichter
- Der „Heute-habe-ich-gelernt-Teiler“ verbreitet neue Tools, erlebte Bugs oder neu entdeckte Bibliotheksfunktionen
- Die „Person mit 700 offenen Tabs“ weiß oft schon, wo sich Informationen finden lassen
- Man braucht auch Menschen, die Fragen beantworten, und Menschen, die Dinge so aufschreiben, dass man sie später wiederfindet
- Dass „grundlegende“ Dinge schwerfallen, ist kein individuelles Problem
- Viele Menschen stoßen aus denselben Gründen an denselben Stellen auf Schwierigkeiten
- Wenn man versteht, warum etwas schwierig ist, kann man das Problem besser beheben – ähnlich wie bei Bugs in Computerprogrammen
- Zu den Ursachen der Schwierigkeit gehören riesige Mengen an Spezialwissen und Fallstricken, 20-Millionen-Zeilen-Codebasen, verborgene Systeme und verwirrende Werkzeugausgaben, die nie wirklich verbessert wurden
- Warum Git schwierig ist, versteht die Vortragende nach eigener Aussage noch nicht vollständig, aber es bleibt ein Thema, über das sie weiter nachdenken und das sie besser verstehen möchte
1 Kommentare
Hacker-News-Kommentare
Am meisten hat mich die Aussage angesprochen: Zeige, was normalerweise verborgen ist.
Solche Tools machen die Lage fast sofort klarer. Wenn man an die Entwicklertools im Webbrowser denkt: In den „dunklen Zeiten“, als es so etwas nicht gab, war es schrecklich, weil man nicht sehen konnte, was passierte, und raten musste.
Ein Tool wie Wireshark, das die Bytes zugänglicher Netzwerkpakete zeigt und sogar ihre Struktur parst, ist nicht nur fürs Netzwerk-Debugging sehr nützlich, sondern auch, um Netzwerkkonzepte zu lehren, weil es nichts verbirgt.
Aus demselben Grund mag ich Open-Source-Software. Man kann sich den Source ansehen, um die Ursache eines Bugs zu verstehen, Wissenslücken zu schließen, die die Dokumentation offenlässt, oder mehr über Programmierkonzepte zu lernen – es ist also nichts verborgen.
Zum Beispiel zeigt es nie die Ethernet-Präambel, die Ethernet-Frame-Prüfsumme nur gelegentlich und den Interframe Gap, der ein notwendiger Bestandteil des Ethernet-Protokolls ist, ebenfalls nie.
Es kommt sehr nah heran, zeigt aber auch, dass irgendwo immer noch mehr Details verborgen sind.
Im Kopf visualisiert man es ohnehin schon, und jede Erklärung von Computing endet letztlich in einem Diagramm. Aber beim Coden gibt es überhaupt keine Diagramme.
Man müsste den gesamten Code dynamisch instrumentieren und Nachrichten an eine GUI schicken.
Auch die Expertinnen und Experten, die dieses Wissen hatten und vermitteln konnten, sitzen heute nicht mehr in den Organisationen selbst, sondern konzentrieren sich bei den Firmen, die solche Tools anbieten.
Deshalb fühlt es sich sofort vertraut an, wenn man ganz natürlich zur Kommandozeile wechselt und sie direkt benutzt.
Julia scheint eine der sympathischsten Personen in der Tech-Branche zu sein.
Jedes Mal, wenn ich ihre Texte lese, kommt diese aufgeregte Begeisterung wieder hoch, die man als Kind hatte, wenn man mit kleinen Experimenten gerade anfing, den Geheimnissen der Realität auf die Spur zu kommen. Wirklich liebenswert.
Zum Glück entdecke ich in letzter Zeit mehr Menschen, die in dieses Muster passen.
Aber Julias Texte vermitteln alle genau diese oben beschriebene aufgeregte Begeisterung.
Die Aussage „Wenn ein Junior sagt: ‘Das ist schwer’, sagt eine erfahrene Person: ‘Stimmt, bash ist unbenutzbar. Niemand versteht es richtig’“ sollte man meiner Meinung nach nicht wörtlich nehmen.
Gemeint ist eher: „Unser Verständnis des von uns geschriebenen bash-Codes oder unser Vertrauen, dass er auch in ungetesteten Situationen erwartungsgemäß funktioniert, ist nicht besonders stark.“
Es heißt, dass man bis zu einem gewissen Grad erwartet, dass bei der kleinsten ungewöhnlichen Situation etwas scheitert und dass man wegen einer neu gelernten Tatsache über bash erschaudert oder so heftig auf einen Gegenstand in der Nähe schlägt, dass er Schaden nimmt.
Bash ist eine komplexe Sprache und für die meisten Programmierer völlig anders als die anderen Sprachen, die sie normalerweise verwenden. In den meisten Unternehmen liegt irgendwo in Produktion ein bisschen bash herum, aber oft gibt es niemanden, der es genug benutzt hat, um sich wirklich gut damit auszukennen.
Ich glaube nicht, dass es Zufall ist, dass Build-Tools, CI-Tools und Cloud-Orchestrierungs-Tools sich in eine Richtung entwickelt haben, die den Bedarf an Shell-Scripting reduziert.
Als Gedankenexperiment: Könnte man bash nicht bessere Zuweisungen hinzufügen? Wenn man zum Beispiel in einem Modus wie
set --goodassetwas wiea = string1 + '.' + string2schreiben könnte, ließe sich ein großer Teil des Shell-Quotings abschneiden.Auch Tools wie
makewürden davon profitieren. Wenn man sechs Monate inmakeinvestieren würde, um brauchbare Variablen, klare Methoden zur Manipulation von Pfaden und Dateinamen sowie nützlichere Targets zu schaffen, wäre das vielleicht besser, als sechs Monate lang komplexe Makefiles zu schreiben.Gerade das Gefühl, dass „bash für die meisten Programmierer anders ist als jede Sprache, die sie normalerweise verwenden“, ist nichts, was Anfänger zwangsläufig ableiten können. Dafür braucht man Erfahrung genug, um den Unterschied zwischen „ungewöhnlich“ und „extrem undurchsichtig“ zu kennen.
In diesem Zusammenhang: Die meiste Software ist überdesignt.
Ich denke, das liegt auch an der Zentralisierung der Branche. Alle werden in Richtung einiger weniger Tools gedrängt, zum Vorteil der wenigen, die diese Tools kontrollieren; dadurch werden viele Tools zu „Tools für alles“ und decken weit mehr ab als die Use Cases, die sie eigentlich bedienen müssten.
Unternehmen wollen, dass alle Entwickler dieselben Tools kennen. So lassen sie sich leichter zwischen Projekten und Firmen austauschen, und ihre Verhandlungsmacht in der Branche sinkt.
Deshalb bleibt in der Software nur ein dominanter Hauptstrang übrig, während alternative Ansätze ohne Jobs ausgegrenzt werden. Die Branche würde sich eigentlich von Natur aus gern dezentralisieren, kann es aber nicht.
Positiv gesehen werden irgendwann wesentlich bessere Nischenansätze auftauchen und den Mainstream-Ansatz aushöhlen. Technologie ist keine Mathematik und auch anders als Wissenschaft; sie kann genügend viele Zweige tragen, die dasselbe Problem auf unterschiedliche Weise lösen.
Damals hielten uns die Browserkriege auf Trab, aber heute sind die Browser weitgehend kompatibel, und trotzdem haben wir eine Menge meist unnötiger Frontend-Komplexität für Web-Apps geschaffen.
Bei Dingen wie DNS, IP und HTTPS lässt sich das nicht vermeiden, weil es grundlegende Technologien sind, in denen Abwärtskompatibilität und politische Faktoren miteinander verwoben sind.
Trotzdem fühlt es sich für mich nach einer besseren Investition an, solche Dinge gut zu lernen, als ein Framework zu lernen. Wenn ich weiterrede, lande ich wohl noch beim Thema Innovation Tokens.
Um Schwieriges einfach zu machen, muss man die passende Abstraktion finden. Man behält nur einen Teil des schwierigen Stoffs und die häufig genutzten Details im Kopf; den Rest schlägt man bei Bedarf nach.
Das Problem ist, dass Menschen für große Themen keine kognitive Komprimierung anlegen, bevor sie sie wirklich brauchen. Weil sie bereits andere große kognitive Lasten tragen, wehren sie sich dagegen, eine neue hinzuzufügen.
Wenn man sich auf jemand anderen verlassen kann, der sich mit einem Thema X gut auskennt, tut man genau das und macht sich nicht unbedingt die Mühe, X ausreichend zu verstehen. Der beste Weg für jemanden, der X gut kennt, weniger um Hilfe gebeten zu werden, ist, anderen zu helfen, das Minimum von X zu verstehen.
set -eist kaputt, ebenso die Notwendigkeit, alles in Anführungszeichen zu setzen, und Globbing sollte eine Funktion sein, die explizit angefordert werden muss. Auf der Kommandozeile wäre das lästig, aber in Skripten ist es etwas anderes; derzeit ist es schwer, dort zu globben, wo man es möchte, wenn man Globbing global abschaltet.Solche schlechten Defaults gibt es nicht nur in Bash, sondern in der gesamten Shell-Familie aus der Ksh- und Bourne-shell-Linie.
Auch bei SQL wollen viele Leute die Reihenfolge der Klauseln ändern. Es gibt keinen Grund, warum das nicht gehen sollte; es wirkt wie eine relativ kleine Änderung, bestehende SQL-Parser dazu zu bringen, Klauseln in anderer Reihenfolge zuzulassen.
Persönlich habe ich dieses kognitive Problem allerdings nicht, vermutlich weil ich weiß, dass ich mir zuerst die Tabellenquelle ansehen muss.
set -ekaputt ist, dass man alles in Anführungszeichen setzen muss und dass Globbing explizit sein sollte, behebt OSH, während es zugleich bestehende Shell-Skripte ausführt.Fügt man am Anfang eines Skripts
shopt --set ysh:upgradehinzu, verschwinden diese drei Probleme.Wenn ihr dem Projekt helfen wollt, wäre es gut, den Tarball herunterzuladen, diese Behauptung zu überprüfen und einen Blogpost darüber zu schreiben.
Weitere Details stehen unter https://www.oilshell.org/release/latest/doc/error-handling.h... und https://www.oilshell.org/release/latest/doc/simple-word-eval....
Die Dokumentation ist umfassend, aber die meisten wollen nicht so viele Details; es wäre daher hilfreich, wenn jemand es testet und kurz darüber schreibt.
Der Grund, warum ich Oils eine Zeit lang nicht aktiv beworben habe, war die Python-Abhängigkeit; inzwischen ist es reines C++ und schlägt Stand dieser Woche Bash in einigen rechenlastigen Benchmarks.
E/A-lastige Skripte waren, wie die meisten Shell-Skripte, schon immer gleich schnell. In der Dokumentation muss Oil noch zu YSH umbenannt werden, daher kann es eine Weile Verwirrung geben: https://www.oilshell.org/blog/2023/03/rename.html
set -eauswendig zu lernen. Immerhin gibt es inzwischen Suchmaschinen.projecteinzuführen, das sich wieselectverhält, aber an der richtigen Stelle stehen kann.Meine Superkraft ist ein schreckliches Gedächtnis. Deshalb muss ich etwas unbedingt verstehen, um es mir merken zu können; ich brauche also kognitive Komprimierung. Ich kann nicht einfach wie normale Menschen lernen.
Heute gelernt: In einer
&&- oder||-Liste beendet die Shell sich nicht, wenn ein Befehl fehlschlägt – mit Ausnahme des Befehls nach dem letzten&&oder||Referenz: https://www.gnu.org/software/bash/manual/bash.html#index-set
/bin/falsetut nichts weiter, als 1 zurückzugeben. Ist das ein Fehlschlag? Nein. Es wurde genau dafür entworfen und ist buchstäblich ein Tool mit diesem ZweckIch habe Hunderte Shell-Skripte geschrieben, und viele Befehle darin geben völlig regulär einen von 0 verschiedenen Wert zurück, um ihre Aufgabe zu erfüllen, etwa zu prüfen, ob ein String einem bestimmten Muster entspricht
Ein Programm kann in jeder Situation jeden gewünschten Exit-Code zurückgeben; konventionell bedeutet 0 Erfolg und ein von 0 verschiedener Wert Fehler. Aber die Shell-Sprache interessiert nur, dass 0 als „wahr“ und ein von 0 verschiedener Wert als „falsch“ ausgewertet wird
Würde die Shell jedes Mal beendet, wenn irgendein Programm einen von 0 verschiedenen Wert zurückgibt, wären
if-Anweisungen und Schleifen unmöglich, was sehr unpraktisch wäreWenn einem Skript der Rückgabecode eines bestimmten Programms wichtig ist, muss es ihn explizit prüfen und behandeln. Wie im verlinkten Abschnitt gibt es Optionen, die die Shell beenden lassen, wenn ein interner Befehl einen von 0 verschiedenen Wert zurückgibt, und viele Shell-Skriptautor:innen auf Anfänger- bis Mittelstufenniveau behaupten dogmatisch, man müsse sie in jedem Skript verwenden
In komplexen Skripten gibt es meiner Erfahrung nach aber viele etwas hackige und schwer handhabbare Edge Cases. Wenn man solche Optionen jedes Mal braucht, ist man mit einem Makefile vielleicht besser bedient
&&und||häufig wie Bedingungen verwendet werden[ -e README ] && cat READMEvermeidet einen Fehler, wenn die README-Datei nicht existiert, und[ -e README ] || echo "You should write a README!"verhält sich umgekehrtDas subtilere Problem ist, dass die Shell selbst mit angenommenem
set -ebei Pipelines nicht beendet wird, solange der letzte Befehl nicht fehlschlägtgrep foo README | sortschlägt nicht fehl, auch wenn README nicht existiert, sofern man nicht zusätzlichset -o pipefailverwendetSelbst wenn man innerhalb der Funktion explizit
set -esetzt, wird das überschriebenIch habe früher einmal ein Beispiel gegeben: https://news.ycombinator.com/item?id=22213830
Der Artikel beschreibt gut Dinge, die so wirken, als sollten sie nicht schwierig sein, tatsächlich aber viel Komplexität enthalten
Der SQL-Teil scheint allerdings eher einen konzeptionellen Fehlschluss weiterzutreiben, statt das Mysterium aufzulösen
Die Logik einer Query ist deklarativ und definiert die Ausgabe. Was eine Ausführungsreihenfolge oder prozeduralen Charakter hat, ist der Query-Plan. Das sollte man zuerst lernen
Danach kann man sich mit Graubereichen wie korrelierten Subqueries beschäftigen. Wenn man erkennen kann, dass
not existsund ein Anti-Join äquivalent sind, kann man es verstehen und darüber schlussfolgernEine Analogie, die nahelegt, man solle die geschriebene Query prozedural verstehen, verschiebt das Problem nur nach hinten; wenn man dann an etwas Komplexerem hängen bleibt, hat man keine Möglichkeit mehr, die gut gemeinte Vereinfachung wieder aufzulösen
Das war ein großartiger Vortrag. Es stimmt, dass Bash voller „Fallstricke“ und Trivia steckt und es schwer ist, alles auswendig zu lernen, aber ich finde, manche Trivia sollte man sich trotzdem merken
Zum Beispiel vergesse ich oft die Reihenfolge der Argumente bei
findund habe vor Maschinen ohne sofortige Internetverbindung schon Zeit damit verloren, mich an die Syntax zu erinnernAlso habe ich beschlossen, die häufigsten Kommandozeilen-Tools und einige ihrer Fallstricke zu lernen und auswendig zu können, und dafür Anki und ein paar Merktechniken genutzt. Der Return on Investment war es meiner Ansicht nach definitiv wert
Tatsächlich habe ich auf eine Buchempfehlung von jvns.ca hin Michael W. Lucas’ Networking for System Administrators gelesen und daraus technisches Wissen sowie nicht wenig Sysadmin-Weisheit in Anki-Karten übertragen
Heute erinnere ich mich beim Debuggen von Problemen auf der Transportschicht sofort daran, wie ich Tools wie netcat und tcpdump einsetzen muss; damit könnte es eines der Bücher mit dem höchsten Return on Investment sein, die ich gelesen habe
Ich habe auch ein Tastenkürzel angelegt, um den zuletzt ausgeführten Befehl dieser Datei hinzuzufügen, sowie eines, um in dieser Datei zu suchen
Die bash-Man-Page ist riesig und komplex, aber umfassend. Wenn man mit den wichtigsten Abschnitten und der visuellen Form des Textes vertraut ist, kann man sie schnell überfliegen und die exakt benötigte Information finden; das hat sich als ziemlich nützlich erwiesen
Oft ist dieser Weg schneller als eine Internetsuchmaschine
Etwa indem man alte Man-Pages in ein texteditorfreundliches Format konvertiert oder bessere Tools wie tldr oder Dash nutzt. Denn
findist nicht das einzige BeispielIch weiß nicht warum, aber ich wollte diesen Artikel irgendwie nicht mögen. Vielleicht, weil jvns zu oft auf HN auftauchte, oder weil ich schlecht gelaunt war.
Aber es ist wirklich ein guter Text, und als jemand mit 20 Jahren Entwicklungserfahrung halte ich ihn für ziemlich nah an der Wahrheit, was Meta-Diskussionen über Programmierung angeht.
Der Punkt mit dem selektiven Blickfeld passt wirklich sowohl auf
digals auch aufman-Pages. Ich kann gar nicht zählen, wie oft ichmangeöffnet habe und von endlosen Konfigurationsoptionen und Kommandozeilen-Flags erschlagen wurde.Mein Tipp für
manist, die Vim-artige Suche mit/zu verwenden. Wenn man zum Beispiel bei grep herausfinden will, wie man die Zeilennummer jeder Übereinstimmung ausgibt, sich aber nicht mehr erinnert, öffnet manman grep, tippt/lineund drückt Enter, um in der man-Page nach Vorkommen von „line“ zu suchen. Der nächste Treffer ist dann einfach/.Dass Strange Loop zu Ende ist, macht mich auch etwas traurig. Ich habe erst etwa letztes Jahr davon erfahren, aber viele Vorträge wirkten außergewöhnlich hochwertig.
Es ist traurig, dass es vorbei ist, aber er zeigt ziemlich überzeugend, dass es manchmal auch gut ist, wenn etwas endet. Wenn man den ganzen Vortrag sieht, versteht man es.
Und ich habe auch https://github.com/kristopolous/mansnip gebaut.
n.Der Sichtweise zu bash widerspreche ich entschieden. Die beste Lösung besteht nicht darin, Tools auf bash zu setzen oder sich ihre Eigenheiten einzuprägen, sondern bash nicht zu verwenden.
Das ist die einzige Möglichkeit, den Fallstricken zu entgehen.
Die häufigsten Alternativen sind 1) eine neue Shell wie die Oil shell [0] zu verwenden oder 2) eine Programmiersprache wie Python, JavaScript oder PHP zu nutzen.
Das Problem bei einer neuen Shell ist, dass man sie überall installieren muss, wo man das Skript verwenden will. bash dagegen ist überall. Wenn es kein Skript ist, das man allein wartet, verlangt man außerdem von anderen, diese Shell zu lernen und zu warten.
Das Problem bei anderen Programmiersprachen ist, dass bash bei dem, was es gut kann – Befehle miteinander verknüpfen sowie Befehlseingaben/-ausgaben und Dateien handhaben –, eine selten gute Usability hat.
Wenn man das in anderen Sprachen versucht, wird es plötzlich viel komplexer oder zumindest deutlich ausschweifender.
Deshalb verwende ich weiterhin bash, erkenne aber an, dass seine Stärke darin liegt, andere Befehle auszuführen und Ein-/Ausgabe zu handhaben. Bei komplexer Logik, die damit nichts zu tun hat, gebe ich sie an eine andere Sprache ab. Manchmal heißt das nicht, bash komplett zu vermeiden, sondern aus bash heraus ein Python-Skript aufzurufen.
Wenn ein anderer Ansatz besser gepasst hat, wäre es schön, wenn ihr ihn teilt.
[0] https://www.oilshell.org
Dieses neue Tool hätte ja auch nicht die Jahrzehnte an Debugging hinter sich, die bash selbst durchlaufen hat. Das Problem liegt in bash selbst.
Wir neigen dazu, Benutzerfreundlichkeit zu unterschätzen und „Cleverness“ zu überschätzen.
Das Paradebeispiel ist Git. Ein sehr cleveres Tool, aber seine Benutzerfreundlichkeit ist furchtbar. Trotzdem wurde es von Linus gebaut, und Linus ist clever, also scheint das Problem bei uns zu liegen.
Wir bekommen das, was wir wertschätzen. Wir sollten Benutzerfreundlichkeit stärker wertschätzen.
Die beste Lösung ist schlicht, Abstand zu halten. Wirklich: aufhören. Man sollte nicht versuchen, den Macho zu spielen.
Das gesamte Modell der Sprache ist grundlegend kaputt. String-zentrierte Typen, globale Modus-Schalter, Ein-Buchstaben-Flags für grundlegende Vergleichsoperatoren, an allen Ecken standardmäßig ignorierte Fehler – und insbesondere Funktionen.
Schon eine einzelne solche Eigenheit würde ausreichen, um eine Sprache auszuschließen; bash hat sie alle und noch mehr.
set -xdas erwartete Verhalten von||und&&stören kann.Welche Sprache stürzt denn überhaupt darüber, dass eine Funktion false zurückgibt? Es gibt Sprachen, die Exceptions werfen, aber ist „false“ nicht ein gültiger Wert, den man zurückgeben darf?
Dasselbe sieht man bei Makefiles. Leute verstehen nicht, was sie tun, haben nie gründlich über Build-Systeme nachgedacht und erwarten deshalb, dass sie sich auf eine bestimmte Weise verhalten.
Zum Beispiel bringt die rekursive Zuweisung in Make fast alle zu Fall.
FLAGS=-b,COMPILE=compile $(FLAGS),$(info compile command=$(COMPILE)),FLAGS=-a,myfile:,echo $(COMPILE) $? -o $@ergibt bei der ersten Info-Ausgabecompile -b, tatsächlich ausgeführt wird abercompile -a -o myfile.Wenn man deshalb alle Zuweisungen sofort auswerten ließe, nur um sie an andere Programmiersprachen anzupassen, würde man einem ein sehr nützliches Werkzeug wegnehmen. Je besser man solche Tools versteht, desto besser weiß man, wofür man sie einsetzt und wie viel Aufwand man hineinstecken sollte.
Trotzdem stimme ich im Großen und Ganzen zu. Alles auch nur ein bisschen Komplexe versuche ich an Skripte in weniger eigenartigen Sprachen auszulagern.
Tools, die einem helfen, in den letzten 5 %, die dann in bash bleiben, Fehler zu vermeiden, sind dabei sehr nützlich.