2 Punkte von GN⁺ 2023-12-10 | 1 Kommentare | Auf WhatsApp teilen
  • JC ist ein Tool, das die Ausgabe vieler CLI-Tools, Dateiformate und einfacher Strings in JSON umwandelt, damit sie in Skripten leichter geparst werden kann
  • Es nimmt Pipe-Eingaben entgegen und gibt JSON über STDOUT aus; außerdem unterstützt es eine Magic Syntax, bei der jc wie in jc dig example.com vor einen Befehl gesetzt wird
  • Die Standardausgabe verwendet ein parser-spezifisches striktes Schema und wandelt Zahlen, null, boolesche Werte sowie zusätzliche semantische Felder um; mit -r oder raw=True lässt sich auf das rohe JSON vor der Vorverarbeitung zugreifen
  • Es kann auch als Python-Bibliothek verwendet werden, sodass Ergebnisse statt als JSON als Python-Dictionary, Liste von Dictionaries oder als lazy Iterable zurückgegeben werden können
  • Für große und lang laufende Pipelines bietet es Streaming-Parser, die JSON Lines/NDJSON ausgeben, außerdem --slurp, --meta-out, lokale Parser-Plugins und Optionen zum Unterdrücken von Plattform-Kompatibilitätswarnungen

Was JC macht

  • JC(JSON Convert) wandelt die Ausgabe vieler CLI-Tools, Dateiformate und einfacher Strings in JSON um
  • Die konvertierte Ausgabe kann per Pipe an Tools wie jq oder jello zur weiteren Verarbeitung übergeben werden
  • Ein Beispiel ist dig example.com | jc --dig, das die dig-Ausgabe in ein JSON-Array umwandelt, gefolgt von jq -r '.[].answer[].data', um nur die IP-Adressen zu extrahieren
  • Dieselbe Aufgabe lässt sich auch mit der Magic Syntax ausführen, etwa jc dig example.com | jq -r '.[].answer[].data'

Nutzung als CLI und Python-Bibliothek

  • Die grundlegende CLI-Nutzung besteht darin, Pipe-Eingaben entgegenzunehmen und eine JSON-Darstellung auszugeben
    • COMMAND | jc [SLICE] [OPTIONS] PARSER
    • cat FILE | jc [SLICE] [OPTIONS] PARSER
    • echo STRING | jc [SLICE] [OPTIONS] PARSER
  • Bei der Magic Syntax wird jc vor einen Befehl oder eine /proc-Datei gesetzt, im Format jc [SLICE] [OPTIONS] COMMAND oder jc [SLICE] [OPTIONS] /proc/<path-to-procfile>
    • Befehls-Aliase und Shell-Builtins werden nicht unterstützt
  • In Python wird es etwa mit jc.parse('dig', cmd_output) aufgerufen
    • Der Rückgabewert kann statt eines JSON-Strings ein Python-Dictionary, eine Liste von Dictionaries oder bei Streaming-Parsern ein lazy Iterable sein
  • Die Dokumentation zum Python-Paket ist über help('jc'), help('jc.lib') oder in der Online-Dokumentation verfügbar

Ausgabedarstellung und Schema

  • Die Standarddarstellung verwendet ein parser-spezifisches striktes Schema
    • Bekannte Zahlen werden in JSON-Werte vom Typ int oder float umgewandelt
    • Bekannte None-Werte werden in JSON null umgewandelt
    • Bekannte boolesche Werte werden ebenfalls umgewandelt
    • Einige Parser fügen zusätzliche semantische Felder hinzu
  • Auf das rohe, vorverarbeitete JSON kann über die CLI-Option -r oder in der Python-Bibliothek mit parse(..., raw=True) zugegriffen werden
  • Die Schemata der einzelnen Parser sind über die Dokumentationslinks neben der Parser-Liste einsehbar
  • Die JSON-Ausgabe ist standardmäßig kompakt; mit der Option -p ist ein Pretty Format möglich
  • Mit den Optionen -y oder --yaml-out ist auch eine YAML-Ausgabe möglich

Unterstützte Parser und Anwendungsbeispiele

  • Unterstützt werden CLI-Befehle, Dateiformate und String-Parser
  • Die Parser-Liste im README enthält unter anderem Dateien und Formate rund um dig, ls, ping, ps, netstat, ifconfig, csv, xml, yaml, /etc/hosts, /etc/passwd, /proc/, systemctl, git log, jwt, url, semver und x509
  • Beispielausgaben zeigen, wie verschiedene Eingaben in JSON-Strukturen umgewandelt werden
    • arp-Ausgaben werden in Felder für Adresse, Hardware-Typ, MAC-Adresse und Interface umgewandelt
    • CSV-Dateien werden in ein Array von Objekten umgewandelt, bei denen die Header als Schlüssel dienen
    • /etc/hosts wird in IPs und Hostname-Arrays umgewandelt
    • ifconfig wird in ein Objekt umgewandelt, das Interface-Namen, MTU, IPv4-/IPv6-Adressen sowie Paket- und Byte-Zähler enthält
    • ping wird in ein Objekt umgewandelt, das die Anzahl gesendeter und empfangener Pakete, Verlustrate, Round-Trip-Zeiten und eine Liste der Antworten enthält
  • In Ansible kann es als Filter Plugin der Collection community.general verwendet werden

Installation

  • jc kann auf verschiedene Arten installiert werden
    • pip3 install jc
    • OS-Paket-Repositories
    • Architektur-spezifische Binaries aus den GitHub Releases
  • Beispiele für Installationen über OS-Pakete sind:
    • Debian/Ubuntu: apt-get install jc
    • Fedora: dnf install jc
    • openSUSE: zypper install jc
    • Arch: pacman -S jc
    • macOS: brew install jc
    • FreeBSD: Installation über Ports
    • Ansible Filter Plugin: ansible-galaxy collection install community.general
    • FortiSOAR Connector: Installation aus dem FortiSOAR Connector Marketplace

Wichtige Optionen

  • -a / --about: Gibt Informationen zu jc und den Parsern als JSON oder YAML aus
  • -d / --debug: Gibt bei Parsing-Problemen Trace-Meldungen aus; -dd bietet ausführlicheres Debugging
  • -h / --help: Gibt die Hilfe aus; mit jc -h --parser_name wird die Parser-Dokumentation angezeigt
  • -M / --meta-out: Fügt der Ausgabe Metadaten wie Zeitstempel, Parser-Name, Magic Command und Exit-Code des Magic Command hinzu
  • -q / --quiet: Unterdrückt Parser-Warnmeldungen; -qq ignoriert Fehler von Streaming-Parsern
  • -s / --slurp: Fasst mehrzeilige Eingaben zu einem Array zusammen
  • -u / --unbuffer: Deaktiviert Output-Buffering
  • -B / --bash-comp, -Z / --zsh-comp: Erzeugt ein Completion Script für Bash oder Zsh

Slice und Slurp

  • Slice verarbeitet mit einer Python-Slicing-ähnlichen START:STOP-Syntax nur einen Teil der Eingabezeilen
  • Bei einer Tabelle mit Header und Footer lassen sich zum Beispiel mit jc 1:-1 --asciitable oder jc 1:4 --asciitable nur die mittleren Daten in JSON umwandeln
  • Positive und leere Slices sind am speichereffizientesten, negative Slices verbrauchen mehr Speicher
  • Slurp ist eine Funktion, mit der String-Parser, die einzeilige Eingaben erwarten, mehrere Einträge auf einmal als Array ausgeben können
    • Beispiel: Eine Datei mit mehreren IP-Adressen, jeweils eine pro Zeile, wird mit jc --slurp --ip-address verarbeitet
  • Die /proc-Magic-Syntax unterstützt bei Auswahl mehrerer Dateien automatisch Slurp
    • Werden mehrere /proc-Dateien konvertiert, wird ein _file-Feld hinzugefügt, damit erkennbar ist, zu welcher Datei das jeweilige Ergebnisobjekt gehört
  • Wird --meta-out zusammen mit Slurp verwendet, wird eine Struktur ausgegeben, die aus einem result-Array und einem _jc_meta-Objekt besteht

Exit-Codes und Metadaten

  • Schwerwiegende interne Fehler in jc erzeugen den Exit-Code 100; andernfalls wird 0 zurückgegeben
  • Bei Nutzung der Magic Syntax speichert jc den Exit-Code des zu parsenden Programms und addiert ihn zum Exit-Code von jc
    • Wenn ifconfig 1 und jc 0 zurückgibt, ist der kombinierte Exit-Code 1
    • Wenn ifconfig 0 und jc 100 zurückgibt, ist der kombinierte Exit-Code 100
    • Wenn beide Fehler liefern, ist der kombinierte Exit-Code 101
  • Wird bei der Magic Syntax --meta-out oder -M verwendet, enthält das _jc_meta-Objekt Informationen zum Magic Command und dessen Exit-Code

Farben und Umgebungsvariablen

  • Mit der Umgebungsvariable JC_COLORS lassen sich Farben für key name, keyword, number und string festlegen
    • Das Format lautet JC_COLORS=<keyname_color>,<keyword_color>,<number_color>,<string_color>
    • Farbwerte sind einer der folgenden Werte: black, red, green, yellow, blue, magenta, cyan, gray, brightblack, brightred, brightgreen, brightyellow, brightblue, brightmagenta, brightcyan, white, default
  • Wird die Umgebungsvariable NO_COLOR gesetzt, wird farbige Ausgabe deaktiviert
  • Die Option -C erzwingt farbige Ausgabe und hat Vorrang vor der Umgebungsvariable NO_COLOR sowie der Option -m

Streaming-Parser

  • Die meisten Parser lesen die gesamte STDIN in den Speicher, parsen sie und serialisieren anschließend ein JSON-Dokument als Ausgabe
  • Einige Streaming-Parser verarbeiten Eingaben zeilenweise, sobald sie eingehen, und geben JSON Lines oder NDJSON aus
    • Beispiele: ls-s, ping-s
    • Bei großen Befehlsausgaben wie ls -lR / kann der Speicherverbrauch stark reduziert werden, und in manchen Fällen kann die Verarbeitung schneller sein
  • Streaming-Parser können nicht zusammen mit der Magic Syntax verwendet werden
  • Damit Parsing-Fehler in lang laufenden Pipelines die Pipe nicht unterbrechen, kann -qq oder in Python ignore_exceptions=True verwendet werden
    • Erfolgreiche Zeilen enthalten _jc_meta.success: true
    • Fehlgeschlagene Zeilen enthalten _jc_meta.success: false sowie die Felder error und line
  • Wenn Ausgaben zwischen Pipes wegen Betriebssystem-Puffern verzögert erscheinen, kann mit -u unbuffered output genutzt werden
    • Bei großen Datenströmen kann unbuffered output jedoch langsamer sein
  • In Python nehmen Streaming-Parser iterable Eingaben entgegen und geben iterable Objekte zurück, sodass eine lazy Verarbeitung möglich ist

Parser-Plugins

  • Lokale Parser Plugins können im Ordner jc/jcparsers des App-Datenverzeichnisses abgelegt werden
    • Linux/unix: $HOME/.local/share/jc/jcparsers
    • macOS: $HOME/Library/Application Support/jc/jcparsers
    • Windows: $LOCALAPPDATA\jc\jc\jcparsers
  • Plugins sind normale Python-Moduldateien
  • Als Vorlage können jc/parsers/foo.py oder jc/parsers/foo_s.py verwendet werden
  • Der Dateiname eines Plugins muss ein gültiger Python-Modulname sein, mit einem Buchstaben beginnen und darf nur alphanumerische Zeichen sowie Underscores enthalten
  • Lokale Plugins können Standard-Parser überschreiben

Locale, Zeitzone und Kompatibilität

  • Für beste Ergebnisse wird empfohlen, LC_ALL auf C oder en_US.UTF-8 zu setzen
  • Auf einigen älteren Systemen unterstützt die Locale C keine UTF-8-Kodierung, sodass UTF-8-Ausgaben auf ASCII und \\u-Escape-Sequenzen zurückfallen können
  • Einige Parser fügen berechnete Epoch-Timestamp-Felder hinzu
    • Wenn der Feldname kein _utc-Suffix hat, gilt er als naive timestamp auf Basis der lokalen Zeitzone
    • Wird die UTC-Zeitzone im Text der Befehlsausgabe erkannt, wird daraus ein timezone aware timestamp, und der Schlüsselname erhält das Suffix _utc
    • Andere Zeitzonen als UTC werden nicht als aware timestamp unterstützt
  • Einige Parser konvertieren plattformspezifische Ausgaben und geben eine Warnung aus, wenn sie auf einer nicht unterstützten Plattform ausgeführt werden
  • Auch auf nicht unterstützten Plattformen können Ausgabedateien anderer Systeme geparst werden; dabei lassen sich Warnungen mit -q oder in Python mit quiet=True unterdrücken
  • Zu den getesteten Plattformen gehören Centos 7.7, Ubuntu 18.04/20.04, Fedora32, macOS 10.11.6/10.14.6, NixOS, FreeBSD12, Windows 10, Windows 2016 Server und Windows 2019 Server

1 Kommentare

 
GN⁺ 2023-12-10
Meinungen auf Hacker News
  • Unter FreeBSD ist dieses Problem mit libxo bis zu einem gewissen Grad gelöst:
    Man kann strukturierte Ausgabe wie mit $ ps --libxo=json | jq erhalten.
    Perfekt ist es nicht: Unterstützung für ls gab es einmal, wurde aber aus irgendeinem Grund entfernt, und nicht alle Utilities unterstützen es.
    jc wirkt wie eine gute Übergangslösung, die Parser für viele Befehle bereitstellt, hat aber die grundsätzliche Einschränkung, Textausgaben zu parsen, die ursprünglich nicht zum Parsen entworfen wurden.
    Es wäre schön, wenn sich Utilities darauf einigen würden, über ein gemeinsames Flag strukturierte Ausgabe zu liefern; auch wenn ein Standard wie bei PowerShell für Unix/Linux wohl zu weit ginge, wäre schon ein standardmäßiges --json-Flag ein großer Fortschritt.
    https://wiki.freebsd.org/LibXo
    https://reviews.freebsd.org/D13959

    • PowerShell geht noch einen Schritt weiter als JSON und unterstützt echte veränderbare Objekte.
      Soweit ich es verstehe, werden nicht nur strukturierte Daten weitergereicht, sondern undurchsichtige Objekte durch die Pipeline geschickt, auf denen man auch Methoden aufrufen kann, die auf frühere Stufen zurückwirken: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_methods?view=powershell-7.4
      Wrapper wie jc, libxo und experimentelle Shells wie https://www.nushell.sh/ gefallen mir ebenfalls, aber sie konzentrieren sich eher auf Datentransport als auf Objekte mit ausführbaren Methoden.
      Strukturierte Daten fühlen sich weiterhin Unix-artig an; wenn man echte Objekte braucht, ist es meiner Ansicht nach Zeit, Python oder Ruby zu starten.
      Egal wie gut eine Shell ist und wie gut ihre Programmierfunktionen sind: Wichtig ist zu wissen, wann man von Shell-Skripten zu einer vollwertigen Programmiersprache wechseln sollte.
    • Ein Blogbeitrag des Autors des ursprünglichen Artikels behandelt genau dieses Thema.
      jc wird dort als Werkzeug vorgestellt, das diese Lücke vorerst füllt, und liest sich als Brücke, bis sich -j/--json-Unterstützung in Unix-Tools allgemein verbreitet hat.
      https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/
    • Auch bei SerenityOS geben Einträge unter /proc ähnlich keine unstrukturierten Textdateien zurück, sondern JSON-Daten.
      Eine stärker strukturelle Lösung könnte darin bestehen, Datenstrukturen aus ELF heraus exportierbar zu machen, diese Datenstrukturen für die Terminalausgabe zu serialisieren und sie dann in vom Nutzer gewünschten Formaten wie JSON oder YAML auszugeben oder weiterzuverarbeiten.
    • Libxo ist in der Theorie schön, aber es sieht so aus, als müssten Anwendungen die Logik für jedes Ausgabeformat selbst implementieren, statt die Struktur an libxo zu übergeben und libxo die Formatierung zu überlassen.
      Ich erinnere mich nicht mehr an das genaue Utility, vermutlich war es iostat, aber es formatierte JSON-Ausgabezeilen per String-Interpolation und erzeugte bei bestimmten Flag-Kombinationen völlig kaputte Ausgabe.
      Ich weiß nicht, ob das inzwischen besser ist, aber bei einer Intervalloption hätte ich eine Art JSON Lines erwartet.
      In Sachen Benutzbarkeit sehe ich PowerShell und kubectl libxo weit voraus.
    • Libxo ist im FreeBSD-Basissystem enthalten, kann aber auch allgemein verwendet werden.
      https://github.com/Juniper/libxo
      https://libxo.readthedocs.io/en/latest/
  • Die Idee ist wirklich gut, aber beim Gedanken an die Wartung werde ich nervös.
    Wenn man Versionsunterschiede, Ausgabeänderungen durch Befehls-Flags usw. berücksichtigt, sieht das nach Wartungshölle aus; in der Praxis wird es in manchen Fällen gut funktionieren, aber jenseits einfacher Standardfälle dürfte der Reiz schnell verfliegen.
    Außerdem wirkt es nicht gut, -- für Tool-Optionen zu verwenden.
    Wenn jeder neue Parser ein neues Flag braucht, könnten Hilfeausgaben oder Manpages Tausende Zeilen lang werden.

    • Wenn man es als Shim betrachtet, dessen Verantwortungsbereich kleiner wird, während immer mehr Kommandozeilen-Utilities JSON-Ausgabe unterstützen, ist es wohl in Ordnung.
      Sobald ein Utility einen eigenen JSON-Export unterstützt, kann dieses Tool später einfach an diese Funktion delegieren.
    • Wenn man in der Dokumentation weiterliest, kann man es auch verwenden, indem man jc vor den Befehl setzt, etwa jc ls.
      Der Parameter --cmd ist sogar eine gute Idee, weil er erlaubt, Daten vor der Umwandlung zu bearbeiten.
      Zum Beispiel möchte man die Liste vor der Konvertierung vielleicht durch grep schicken.
      Auch aus Wartungssicht gilt: Wenn sich die Ausgabe grundlegender Unix-Befehle stark ändert, zerbricht das nicht nur dieses Tool, sondern auch zahllose Skripte; deshalb dürfte es durch Updates anderer Binaries nicht so oft kaputtgehen, wie man zunächst denkt.
    • Einerseits bin ich hin- und hergerissen.
      Ein gut gepflegtes gemeinsames Parser-Bündel ist besser als überall verstreute Ad-hoc-Parser für Ausgaben; wenn man aber etwas Komplexes tun will und deshalb direkte JSON-Ausgabe braucht, sollte das Parsen selbst dem Problem möglichst nichts hinzufügen.
      Um das bequem zu nutzen, müsste ich wohl für alles, was ich verwenden will, zusätzliche Testfälle als PR einreichen.
      Diese Tests hätte ich ohnehin selbst schreiben müssen.
    • Das braucht Zusammenarbeit.
      Es geht kaum anders, als dass Leute Parsing-Informationen für die benötigten Tools einreichen und Nutzer sie leicht aktuell halten können.
    • Das ist einer der besseren Einsatzzwecke für LLMs, die sich darin als gut erwiesen haben, unstrukturierten Text in strukturierte Objekte umzuwandeln.
  • Nushell verfolgt zwar einen anderen Ansatz, landet aber größtenteils am selben Punkt: strukturierte Daten aus Shell-Befehlen
    Meist übernimmt die Shell selbst diese Rolle
    http://www.nushell.sh/

    • Nushell hat eine from json-Operation und passt daher tatsächlich gut zu JC
      Ich habe früher ein Video aufgenommen, das einige gute Funktionen von Nushell zeigt; etwa bei Minute 19 geht es um die Kombination mit jc: https://www.youtube.com/watch?v=KF5dtxVsn1E
    • Seit Nushell erstmals vorgestellt wurde, habe ich gelegentlich hineingeschaut, aber erst vor ein oder zwei Monaten habe ich den Kern endlich richtig verstanden
      Ich wollte gerade ein Skript schreiben, das Dateien in Verzeichnissen nach einem bestimmten Muster durchsucht und diejenigen entfernt, deren Änderungszeiten innerhalb von 10 Minuten voneinander liegen, als mir einfiel, dass Nushell für solche Dinge gut geeignet ist
      Nach kurzem Herumprobieren hat es endlich Klick gemacht, und jetzt bin ich ziemlich begeistert
      Selbst bei unstrukturierten Daten ist es sehr mächtig, wenn man sie in etwas wie eine Liste von Records umwandeln und dann verarbeiten kann
  • In gewisser Weise ist es großartig, dass überall Dateien sind; das ist das Unix-Versprechen, und in Plan 9 wurde es noch weiter ausgebaut
    Aber unstrukturierte Dateien oder Dateien mit jeweils eigenen Formaten bremsen einen genauso stark aus
    Schon der Versuch, eine einzelne nginx-Logdatei nur mit etwas wie awk zu parsen, kann lästig sein
    Einer der großen Nachteile ist, dass es im Linux-Userspace schwer ist, groß angelegte Systemneuschreibungen oder Designänderungen umzusetzen
    Ich wünsche mir eine intelligentere Shell, ich mag Dateien, und auch das awk-Buch liegt neben mir, aber inzwischen ist es an der Zeit für ernsthafte Verbesserungen beim Datenparsing
    So wie Programme selbst entscheiden können, ob sie farbige Ausgabe rendern sollen, wäre es gut, wenn sie auch strukturierte Ausgabe liefern könnten

    • Ein Teil des Problems ist, dass Befehlsausgaben Benutzeroberfläche und API zugleich sind
      Jede Text-UI kann wie eine API verwendet werden, deshalb bekommt menschenlesbarer Text Priorität
      Shell-Scripting ähnelt daher dem Erstellen von Browser-Erweiterungen von Drittanbietern
      Man schaut hin, stellt Vermutungen an, bastelt auf dieser Grundlage schnell einen Parser zusammen und hofft, dass es funktioniert
      Es wäre gut, einen dritten Standard-Ausgabekanal für maschinenlesbare Inhalte zu haben
      Das Terminal würde ihn standardmäßig nicht ausgeben; beim Piping würde diese Ausgabe weitergeleitet, sie sollte JSONL sein, und die Manpage würde den Vertrag festschreiben
      Dann könnte stdout für Menschen bleiben, und wenn man es parst, wüsste man, dass es zwar möglich, aber fragil ist
      Natürlich wäre das eine völlig rückwärtsinkompatible Idee, und wenn man die CLI unrealistisch von Grund auf neu erfinden und modernisieren würde, gäbe es eine lange Liste von Dingen, die man ändern wollte
    • Vor einem halben Jahrhundert kamen ziemlich gute Ideen auf, und es ist frustrierend, dass viele sie nicht als etwas betrachten, das verbessert werden kann, sondern wie ein Evangelium behandeln
      Verbesserungen durchzusetzen ist auch wirklich schwer, und wenn jemand wie Lennart versucht, jahrzehntealten alten Ballast wegzuräumen, gibt es sofort Drama
      Auch JSON ist noch nicht vollkommen
      JSON ist eine halbwegs gute Idee, aber wenn man es richtig machen will, braucht man ein Format, das Dinge wie Datentypen sichtbar machen kann
      Es müsste eher in Richtung PowerShell gehen, damit man Zahlen als Zahlen behandelt und erstaunliche Dinge wie die Berechnung der Differenz zwischen Datumswerten mit $a - $b machen kann
    • Eine einfachere Verbesserung wäre, in allen CLI-Tools per Kommandozeilenargument JSON-Ausgabe zu implementieren
      Es wäre schön, wenn das in den GNU coreutils umgesetzt würde
    • PowerShell bleibt immer eine Option
      Das Problem ist, dass sie so tief in .NET und Objekten verwurzelt ist, dass die Integration mit bestehenden nativen Befehlen auf jeder Plattform sehr schwierig ist
    • Beim Parsen von Serverlogs ist es schade, dass man solche Funktionen nicht aus Dingen wie logstash herauslösen kann
      Denn im Kern machen sie bereits dasselbe
      Das Endziel dürfte aber letztlich sein, dass übergeordnete Tools den Wert erkennen und selbst strukturierte Ausgabe bereitstellen
  • Schön
    Ich unterstütze CLI-Tools mit sinnvoller JSON-Ausgabe sehr, und Dinge wie https://github.com/WireGuard/wireguard-tools/blob/master/contrib/json/wg-json sowie PowerShells |ConvertTo-Json machen einen großen Teil der Verwaltungs-/Monitoring-Automatisierung aus
    Allerdings leistet das Wort sinnvoll hier viel Arbeit, und die Realität ist nun einmal die Realität
    Wie bei LSI/Broadcom StorCLI, wo man ein J an den Befehl anhängt, oder bei PowerShells COM-verbergenden Wrappern ist es zwar technisch JSON, aber das Ergebnis ist oft absurd kompliziert oder nutzlos, sodass man am Ende doch wieder zum Provisorium „einfach ein paar Regexes über die Klartextausgabe laufen lassen“ zurückkehrt
    Trotzdem werde ich mir das auf jeden Fall ansehen
    Wenn das erste Beispiel, das Parsen der dig-Ausgabe, repräsentativ für Dinge ist, die sich stabil erledigen lassen, könnte das ziemlich interessant sein

  • Ich finde, jc dig example.com sollte die Standardsyntax sein
    Denn bei dig example.com | jc --dig muss man später die Flags und Parameter des vorherigen Befehls erraten, um die Ausgabe zu parsen

  • Dass jede Ausgabe ein Objekt ist, gehört zu meinen Lieblingsaspekten von PowerShell
    Das vermisse ich jedes Mal, wenn ich ein bash-Skript schreiben muss

  • Respekt vor der Person, die sich vorgenommen hat, das zu warten

    • Ebenso Respekt vor der Person, die dieses Tool tatsächlich nutzt und dabei auf die Stellen stößt, an denen es falsche Annahmen trifft
    • Ich frage mich, wie Versionsprobleme behandelt werden sollen
      So etwas wie aws s3 ls | jc --aws=1.2.3 wäre ein Albtraum
    • Guter Punkt
      Das erinnert mich an das file-Programm unter Linux oder Unix und an die Heldinnen und Helden, die es pflegen
    • Theoretisch könnte man, wenn sich etwas wie plugins laden ließe, zum Beispiel in Form separater Shell-Befehle, einen Teil des Wartungsaufwands an Plugin-Autoren weitergeben
  • Ich frage mich, ob es eine Liste moderner Unix-Kommandozeilentools gibt, die eine --json-Option akzeptieren.
    Es könnte nützlich sein, solche Informationen zu diesem Repository hinzuzufügen.

    • Unter FreeBSD wird über libxo praktisch fast alles unterstützt.
    • Eine Liste habe ich nicht, aber ip, der moderne Ersatz für ifconfig, unterstützt JSON.
      lldpctl unterstützt es ebenfalls.
      Ansible stellt Systemdetails als JSON namens facts bereit, und Automatisierung ist darauf ausgelegt, diese zu nutzen.
    • lsblk akzeptiert das Flag --json und kann viele Informationen liefern.
      Man kann lsblk --json --output-all ausprobieren.
      Das ist sehr nützlich, wenn ein Skript die Festplatten und Partitionen eines Systems prüfen muss.
    • TShark, das CLI-Begleittool von Wireshark, unterstützt dies mit dem Flag -T json.
    • Vielleicht nicht die beabsichtigte Antwort, aber es gibt die AWS CLI.
  • Interessantes Projekt.
    Ich hätte allerdings erwartet, dass als Parser der ersten Stufe etwas wie textfsm verwendet wird.
    textfsm wird häufig zum Parsen der CLI-Ausgabe von Netzwerkgeräten genutzt.
    https://github.com/google/textfsm