Welcome!

I'm Martin Häcker, a software developer with more than 20 years of experience. I can assist with all aspects of professional software development.

My blog is about Software, Liquid Democracy, Go / Baduk / Weiqi, Kochen, choir singing, bouldering, billiard, paragliding, kiting, juggling and other things that interest me. Look around, use my code and subscribe to my feed to enjoy reading the blog in the comfort of your feed reader.

While my website is available in English and German, most of my blog will be single language. Mostly in German, but occasionally in English.

Newest Entries:

Arbeiten mit JSON & YAML auf der Shell

written by Martin Häcker on

yaml ganz angenem auf der Shell

Arbeiten mit strukturierten Datenformaten auf der Shell kann anstrengend sein – wenn man noch nicht die richtigen Tools dafür hat. Ob JSON aus einer API, YAML aus Kubernetes-Manifests oder riesige Logfiles – ohne passende Helferlein endet man schnell bei unübersichtlichem grep, less und Copy&Paste.

Zum GlĂĽck gibt es eine Reihe von Werkzeugen, die genau dafĂĽr gemacht sind:

In diesem Beitrag stelle ich euch diese Tools vor – mit Beispielen, die ihr direkt in eurer eigenen Shell ausprobieren könnt.


jq – der Klassiker für JSON

Das vermutlich bekannteste und am weitesten verbreitete Tool fĂĽr JSON ist jq. Es ist so etwas wie der Schweizer Taschenmesser fĂĽr JSON:

  • formatiert unlesbare Minified-JSON-Dateien,
  • extrahiert gezielt Werte,
  • filtert und transformiert Daten,
  • eignet sich fĂĽr einmalige Ad-hoc-Analysen genauso wie fĂĽr Skripte.

Ein einfaches Beispiel: JSON schön formatieren:

$ cat data.json
{"user":{"id":42,"name":"Alice"},"active":true}
$ cat data.json | jq # oder `jq < data.json`
{
  "user": {
    "id": 42,
    "name": "Alice"
  },
  "active": true
}

So schnell wird aus einem unĂĽbersichtlichen Einzeiler eine lesbare Struktur.

Mann kann es aber auch super in scripten verwenden um Daten aus json zu extrahieren:

get_current_gitlab_token() {
    kubectl get secret $SECRETNAME -n $INITIALNAMESPACE -o json |
        jq -r '.data[".dockerconfigjson"]' 2>/dev/null |
        base64 --decode |
        jq -r '.auths["registry.gitlab.com"].password' 2>/dev/null
}

Oder um in einem JSON-File Daten einzutragen:

kubectl get secrets shipa-certificates -o json \
        | jq ".data[\"ca.pem\"] |= \"$CA_CERT\"" \
        | kubectl apply -f -

jq kann noch viel mehr. Wer das Werkzeug noch nicht kennt sollte unbedingt ein paar Minuten investieren um das Tutorial querzulesen, und dann bei der nächsten Einsatzmöglichkeit gezielt nach der Syntax schauen. Pro tip: KI's können diese Syntax prima, und jless (kommt gleich) kann diese auch generieren.


jo – JSON in der Shell erzeugen

Während jq ideal zum Lesen und Transformieren ist, eignet sich jo perfekt, um JSON direkt in der Shell zu erstellen. Damit lassen sich Testdaten oder API-Payloads schnell zusammenbauen.

Ein einfaches Beispiel:

jo name=Alice age=30 active=true

Ausgabe:

{"name":"Alice","age":30,"active":true}

Auch Arrays sind möglich:

jo -a red green blue

âžś ["red","green","blue"]

Verschachtelte Objekte:

jo user=$(jo name=Alice id=42) project=Demo

âžś {"user":{"name":"Alice","id":42},"project":"Demo"}

Das eignet sich sehr gut fĂĽr schnelle curl-Requests, aber insbesondere auch fĂĽr shell scripte in denen inline json sonst sehr schnell sehr unĂĽbersichtlich wird:

curl -X POST -H "Content-Type: application/json" \
     -d "$(jo username=dev password=secret)" \
     https://example.com/api/login

yq – YAML lesen und bearbeiten

YAML verwenden wir ĂĽberall, am meisten habe ich in Kubernetes damit zu tun. yq ist das Werkzeug der Wahl, um YAML-Dateien zu lesen, zu durchsuchen und zu editieren. Die Syntax ist sehr nahe an jq, das Werkzeug kann neben YAML aber auch JSON, TOML und XML verarbeiten, und zwischen diesesn Konvertieren. Im wesentlichen kann es das gleiche wie jq, eben auch fĂĽr YAML.


jless & yless – interaktiv stöbern

Wenn Dateien zu groß oder zu komplex werden, helfen jless und yless (ein alias yless=jless --yaml. Sie bieten eine interaktive Ansicht für JSON und YAML – mit:

  • Syntax-Highlighting,
  • Falten und Aufklappen von Strukturen,
  • komfortabler Navigation und Suche.

Beispiel:

kubectl get pods -oyaml | yless

Das schöne: Man kann hier auf der Shell wunderbar uninteressante textblöcke einklappen um schnell die wichtigen Informationen zu fokussieren, und dann über Tastaturkommandos werte, oder jq/yq filter auf das aktuell ausgewählte Element kopieren, um das z.B. dann auf alle Pods in einem Namespace anzuwenden.


Fazit

Mit diesen Tools – jq, jo, yq, jless und yless – wird das Arbeiten mit JSON und YAML auf der Shell deutlich angenehmer. Sehr gut investierte Zeit diese Werkzeuge (eines nach dem Anderen) zu lernen.

Mit llm RAG einfach mal ausprobieren – direkt von der Shell

written by Martin Häcker on

Ablaufdiagramm Einer der coolsten Aha-Momente der letzten Tage bei mir war, wie einfach und niederschweflig das Arbeiten mit Retrieval-Augmented Generation (RAG) von der Shell inzwischen sein kann – ganz ohne spezielle Infrastruktur, Vektor-Datenbank oder Server-Backend. Das Python-Tool llm macht das möglich: RAG direkt aus der Kommandozeile, mit SQLite als Backend und einfachen Kommandos, die sich hervorragend in Shell-Workflows integrieren lassen.

Ein Power Tool fĂĽr Sprachmodelle in der Shell

llm kann natürlich noch viel mehr und ist ein Power Tool, das den Einsatz von KI direkt im Terminal erlaubt. Es erlaubt mit beliebigen API-Providern oder lokalen Modellen zu sprechen und integriert diese damit nahtlos in eigene Skripte. Use Cases: Daten hinein pipen und mit dem LLM bearbeiten. Ob zusammenfassen, erklären, übersetzen, mit einem aufwendigen Prompt aus einer Datei beackern… Da geht so viel. Egal was Ihr aus diesem Artikel mitnehmt, zumindest sollte es sein das Ihr llm in euren Workflow aufnehmt und installiert.

Der RAG-Workflow von der Shell aus

Ein kompletter RAG-Workflow funktioniert mit llm in wenigen Schritten. Diese Demo hier hab ich von Simon Willison geklaut, dem Autor von llm. Hier wird semantische Suche in den Python Enhancement Proposals demonstriert. Dieses Tutorial verwendet einen lokalen LLM-Server, man kann das aber natürlich auch mit GitHub Copilot oder ähnlichen Modellen machen. Herauszufinden wie die dort heißen und zu verbinden sind bleibt ein Exercise für den Leser.

1. Dateien vorbereiten

Wir erstellen gekĂĽrzte Versionen von Textdateien:

mkdir -p peps-truncated
for f in peps/*.rst; do
  head -c 8000 "$f" > "peps-truncated/$(basename "$f")"
done

Das ist natĂĽrlich streng genommen falsch, weil wir ganz viel Daten wegschmeiĂźen. Einiges spricht aber trotzdem dafĂĽr:

  1. Gerade lokale Modelle haben gerne nicht so groĂźe Kontext-Fenster und da muss das Dokument reinpassen.
  2. Meistens steht am Anfang eines Dokuments worum es geht. Für unsere Zwecke also eine gute Näherung.

Um das später in ein Produkt umzuwandeln müssten wir uns noch weitere Strategien anschauen, z.B. mit einem Sliding Window über die Dokumente zu gehen und für jeden Abschnitt ein Embedding zu erzeugen. Grundsätzlich ist es aber eine gute Idee verschiedene Indexe zu erzeugen die unterschiedliche Zwecke erfüllen.

2. Vektor-Index erstellen

llm embed-multi peps \
    -m mxbai-embed-large \
    --files peps-truncated 'pep-3*.rst' \
    -d peps.db \
    --store

Das erzeugt eine SQLite-Datenbank mit eingebetteten Vektoren. Wichtig: Die Datenbank speichert auch, mit welchem Modell die Einbettung erfolgte – bei weiteren Operationen auf der gleichen Collection peps ignoriert llm den Modell-Parameter ohne Fehlermeldung!

Seiten-Notiz: Embeddings, was ist das? Ein Embedding ist eine Umwandlung von einem Text in eine Zahlenreihe (Mathematisch: Einen Vektor). Jeder dieser Vektoren beschreibt eine Koordinate in einem Hoch-Dimensionalen Raum, mit der Eigenschaft, das Koordinaten die sich Nahe sind von einem Text kommen der semantisch Ähnlich ist. Darin kann man sogar Rechnen, ein etwas überstrapaziertes Beispiel wäre z.B. der Vektor für König + Weiblich = Königin. Mehr gibts hier

3. Abfragen stellen

llm similar -c "What do string templates look like?" \
  -d peps.db -n 2 peps \
  | llm -s "Answer the question: What do string templates look like?" \
    -m devstral -o num_ctx 256_00

Hier wird erst ähnliche Inhalte zur Frage gesucht. Wichtige Details: Das Kontext-Fenster des Sprachmodells das antwortet muss groß genug sein, das es alle Antworten in seinen Kontext aufnehmen kann. Ansonsten wird gerne der Anfang abgeschnitten - und da steht natürlich der Treffer mit dem besten Score.

4. Automatisieren

Wir können sogar direkt ein Skript generieren lassen:

llm '
Build me a bash script like this:
./pep-qa.sh "What do string templates look like?"
It should first run:
llm similar -c $question -d peps.db peps
Then it should pipe the output from that to:
llm -s "Answer the question: $question" -m gpt-4.1-mini
That last command should run so the output is visible as it runs.
' -x > pep-qa.sh

Fazit

Was früher nach viel Setup aussah (Vektor-Datenbank, Backend-API, RAG-Pipeline), ist heute in wenigen Shell-Befehlen machbar. SQLite funktioniert dabei erstaunlich gut – llm führt einfach einen Full-Table-Scan durch und berechnet die Vektor-Abstände direkt. Das ist nicht hyper-skalierbar, aber bis 10.000 bis 100.000 Einträge durchaus brauchbar.

Und das Beste: llm lässt sich überall in bestehende Shell-Skripte und Workflows einbauen – sogar mit piped Input. Wer also mal eben eine intelligente Suche oder ein Sprachmodell in seinen CLI-Workflow integrieren will, findet hier ein extrem mächtiges Toolset.

Ich kann nur empfehlen ein Shell-Werkzeug wie llm zu lernen.

DevOpsCon Keynote – Security ist jetzt Teil von DevOps?

written by Martin Häcker on

Metapher auf Teams die jeweils Sicherheits-Interessierte enthalten, die einfach von Spezialisten Unterstützung erhalten können

Ich konnte auf der DevOpsCon der Keynote "From Static to Strategic: Reimagining Application Security for a DevOps World" von John D. Wood nicht entgehen. Um ehrlich zu sein: Die Keynote hat mich nicht begeistert. Am ehesten noch fand ich interessant das er Zahlen hatte, das die meisten Sicherheitslücken (auch nach Bekanntwerden) noch über ein Dreiviertel-Jahr offen sind. Aua. Ein Satz am Ende ist bei mir hängengeblieben:

"DevOps bekommt jetzt auch Security."

Was simpel klingt, ist in der Realität alles andere als einfach – und betrifft uns ganz konkret. In einer Zeit, in der wir als Unternehmen KRITIS-relevant geworden sind, ist es für viele Risiken nicht mehr möglich sie einfach zu übernehmen (AKA aussitzen). Wir müssen sie aktiv mitigieren – und das gilt besonders auch für Security-Risiken.

Security: Aus DevOps wird "DevSecOps"?

Dev ist schon schwer. Ops noch schwieriger. Und jetzt kommt Security obendrauf. Nicht jedes Team kann oder will alle drei Disziplinen gleich gut abdecken. Und dennoch ist klar: Es kommt mehr Arbeit auf uns zu.

Wir werden bei bestimmten Anwendungen in Zukunft viel stärker darauf achten müssen:

  • Dass Betriebssysteme (in Docker-Containern) aktuell sind,
  • Dass Projektabhängigkeiten regelmäßig gepflegt werden,
  • Dass wir verstehen, welche SicherheitslĂĽcken fĂĽr uns relevant sind – nicht nur, weil ein Scanner sie anmeckert, sondern weil unsere eigene Risikoabwägung sie als kritisch einstuft.

Wunsch-Szenario: Expertise teilen, nicht duplizieren

Mein Wunsch wäre, dass nicht jedes Team die komplette Security-Expertise selbst aufbauen muss. Stattdessen sollten sich diejenigen, die sich besonders für das Thema interessieren, tiefer einarbeiten können – und jederzeit unkompliziert Zugang zu Spezialist\:innen haben. Idealerweise entsteht daraus eine Art Mentoring-Beziehung.

Das Ziel: Schnell und unbĂĽrokratisch Expertise bekommen, wenn man merkt, dass man sie braucht. Entwickler\:innen sollen lernen, Security-relevante Situationen zu erkennen und wissen, wo sie gezielt und niederschwellig UnterstĂĽtzung finden.

Compliance-Checkbox oder echte Verteidigung?

Ein starkes Bild aus dem Vortrag war die Kritik an klassischen Security-Prozessen: Wöchentliche Scans, lange Backlogs mit offenen CVEs, endlos False Positives, wenig konkreter Nutzen. All das erzeugt ungeplante Arbeit, und widerspricht damit dem DevOps-Grundsatz "No unplanned work" – und hilft im Ernstfall wenig. Letztlich müssen wir ja die Daten unserer Versicherten Schützen, dass der Bug den ein Angreifer bei uns Ausgenützt hat schon lange bekannt war, hilft uns nicht weiter.

Fazit

Ich nehme aus dem Talk vor allem eines mit: Security können wir in Zukunft nicht länger als "Problem von jemand anderem" verstehen. Sie ist jetzt (oder wird es bald) integraler Teil von DevOps – ob uns das passt oder nicht.

Und wir müssen Wege finden, wie wir das gemeinsam schultern können – weil wir eben nicht jeden Entwickler zum Security-Experten machen können.

Weitere Beiträge…