inxi :: json / xml output
Page Updated: 2024-03-07 inxi version: 3.3.33
This page is put up to try to help users who may be trying to use the --output json/xml feature of inxi but do not understand what the output is. It is NOT intended as a tutorial on how to program, how to import json/xml, how to handle json/xml data structures, or anything like that. If that is what you are looking for, then you should learn how to use json/xml effectively first, then come back to the json inxi exports once you do understand how to work with data at that level.
The problem of how to use json/xml output
Sometimes I get questions from confused users who were trying to parse inxi json/xml output with bash or simply don't understand the output, and don't understand the sorters, that part is worth documenting because it's not easy to understand. Note that I will NOT help anyone learn how to program, that's up to the end user to learn.
Sample code repo issues/questions
- Escape sequences in exported JSON
with --tty #270
I'm trying to run inxi 3.3.15-00 (2020-04-08) as part of a job script that runs in a SLURM cluster, and the JSON generated by it is full of escape sequences, probably from the colors.
- uncolored json output #280
I try to use inxi 3.3.01-00 (2021-02-08) om Debian Bullseye and get JSON output from inxi. But always have outpit with ANSI colors (I guess):
I would like to take slight issue with the assumption that I am so incompetent that I would export non data like colors into json key:value pairs or arrays. This is not the case, nor is this data format an accident or unintended. This is why issues about this will always be closed as invalid.
The basic explanation, no TLDR version!!
We will consider the above being the questions being asked here, and the following the answer. Note that if you feel you need tldr; version, then this feature is simply not meant for you.
A: Those aren't escape sequences, they are the primary sorters for the output. Perl has random hash key storage, in order to output the items in the correct order, and the correct indentation levels, the sorters are added. Note that outputting the raw json to file isn't going to do you any good until you write the json parser tool that will then resort the hash keys into the proper order, then output them correctly, after stripping off the sorters and indenters.
Basic requirements for handling the data
inxi output is extremely complicated and non-trivial to use and work with, so you need at a bare minimum the following:
- a real programming language to parse the json/xml
- a way to sort the json keys, recursively, or, ideally, to just turn the json/xml back into a hash then sort its keys that way, with the real language
- the ability to understand the sorters, and to, after sorting the hash, remove them from the visible output.
- ideally, also, is to understand the indentation method as well, and use that to determine child/parent relationships, though that's harder, I'd nudge that towards expert mode.
Note you have no way of knowing which items are children or parents of which other item without this. The following output doesn't just magically happen, it happens because of the sorters in the keys.
json/xml output samples
So we are clear about what we are talking about, here are json and xml outputs for inxi -Saz.
JSON:
inxi -Saz --output json --output-file print [{"000#1#0#System":[{"003#1#2#compiler":"gcc","000#1#1#Kernel":"6.1.0-3.1-liquorix-amd64","002#0#2#bits":64,"001#0#2#arch":"x86_64","004#0#3#v":"12.2.0","005#0#2#parameters":"audit=0 intel_pstate=disable hpet=disable rcupdate.rcu_expedited=1 BOOT_IMAGE=/boot/vmlinuz-6.1.0-3.1-liquorix-amd64 root=UUID=4f6b4acd-fa5c-400e-8b48-364b1f44dd17 ro quiet"},{"006#1#1#Desktop":"Xfce","015#0#3#v":"1.26.0","011#1#2#wm":"xfwm","012#0#3#v":"4.16.1","010#0#2#info":"xfce4-panel","013#0#2#vt":"7","007#0#2#v":"4.16.1","008#1#2#tk":"Gtk","016#1#1#Distro":"Debian GNU/Linux bookworm/sid","009#0#3#v":"3.24.34","014#1#2#dm":"LightDM"}]}]]
XML:
inxi -Saz --output xml --output-file print <perldata> <arrayref memory_address="0x5624049bc560"> <item key="0"> <hashref memory_address="0x562404098878"> <item key="000#1#0#System"> <arrayref memory_address="0x562404098890"> <item key="0"> <hashref memory_address="0x5624040988c0"> <item key="000#1#1#Kernel">6.1.0-3.1-liquorix-amd64</item> <item key="001#0#2#arch">x86_64</item> <item key="002#0#2#bits">64</item> <item key="003#1#2#compiler">gcc</item> <item key="004#0#3#v">12.2.0</item> <item key="005#0#2#parameters">audit=0 intel_pstate=disable hpet=disable rcupdate.rcu_expedited=1 BOOT_IMAGE=/boot/vmlinuz-6.1.0-3.1-liquorix-amd64 root=UUID=4f6b4acd-fa5c-400e-8b48-364b1f44dd17 ro quiet</item> </hashref> </item> <item key="1"> <hashref memory_address="0x5624049c0c28"> <item key="006#1#1#Desktop">Xfce</item> <item key="007#0#2#v">4.16.1</item> <item key="008#1#2#tk">Gtk</item> <item key="009#0#3#v">3.24.34</item> <item key="010#0#2#info">xfce4-panel</item> <item key="011#1#2#wm">xfwm</item> <item key="012#0#3#v">4.16.1</item> <item key="013#0#2#vt">7</item> <item key="014#1#2#dm">LightDM</item> <item key="015#0#3#v">1.26.0</item> <item key="016#1#1#Distro">Debian GNU/Linux bookworm/sid</item> </hashref> </item> </arrayref> </item> </hashref> </item> </arrayref> </perldata>
Note a few things in particular:
- You can NEVER assume the numeric key sorter number!! Those are fluid and dynamic, and simply mean the next item follows the previous item. Period.
- This sample has two v in the same line, thus, you could never strip the sorters and then get meaningful results without processing the data BEFORE you strip them out.
inxi internal data structure
To begin to understand how to use this output you have to understand the inxi data structure:
- A good way to see how the data is structured is to use the --output xml --output-file print option, that for some reason does sort the keys into order, Perl json doesn't (inxi uses 1 of 3 json export modules, and getting a global sorted output from those proved too difficult, so I gave up).
- inxi is made out of 1 or more 'items', an item is for example System, Graphics, etc, or the 'short' form, which has no primary Item line starter.
- Each item is made out of 1 or more rows. A row is what you will see if you use -y -1, no wrap of long llines. Most items have more than 1 logical row, except for Info.
- Each row is made up of 1 or more key value pairs.
- A single row can contain keys with the same name, like v:, but you can NEVER sort by key name without the sorters because you will just end up with a big jumbled up incoherent mess of random key: value pairs.
- Each key value pair can have 0 to 1 or more children, that is, each key value pair is either a parent, or a child without further children
- Each child can be a child, or be a parent of its own children.
- A small set of features, --repos for example, do not use hashes, but rather use arrays, for their results. They require a different logic to output them. More accurately, they are a hash key containing a set of hash keys, each with an array as its value, roughly speaking.
- Some features use recursive logic, and so these levels can get pretty deep. If you don't know how to do recursive logic, you will not have much luck with some advanced features. I would put recursive output items in the 'Advanced' programming field. The best way to avoid recursive stuff is to avoid verbose output modes for recursive features, like --logical.
- The best handlers for this logic would be intrinsically recursive.
Key sorters / indenters
The key sorter/indenters:
000#0#0#
- # are the separators for the sort/indent values
- 000 - the main key sorter, from 0 to 999 for each 'row'.
- first digit after first # is possible parent (1) or child with no children (0). Not all possible parents have children, but they can.
- digit after second #, the indentation level of the item.
- String or value after the 3rd #, the key name, what you see in print/screen/output
Basic approaches
I would not waste any time trying to do this in Bash, unless you like pain. In Perl, to sort hash keys when you are going to use them you do:
foreach my $key ( sort keys %data){ do stuff... }
Visual sample of data structure with -y 1
The following may be useful as a visual aid to understanding how the data structure and key components work:
pinxi --gpu -y1 Graphics: Device-1: AMD Cedar [Radeon HD 5000/6000/7350/8350 Series] vendor: XFX Pine driver: radeon v: kernel alternate: amdgpu arch: TeraScale 2 code: Evergreen process: TSMC 32-40nm built: 2009-15 pcie: gen: 1 speed: 2.5 GT/s lanes: 16 link-max: gen: 2 speed: 5 GT/s ports: active: DVI-I-1,VGA-1 empty: HDMI-A-1 bus-ID: 0a:00.0 chip-ID: 1002:68f9 class-ID: 0300 Display: x11 server: X.Org v: 1.21.1.3 with: Xwayland v: 22.1.0 compositor: xfwm v: 4.16.1 driver: X: loaded: modesetting gpu: radeon display-ID: :0.0 screens: 1 Screen-1: 0 s-res: 2560x1024 s-dpi: 96 s-size: 677x270mm (26.65x10.63") s-diag: 729mm (28.7") Monitor-1: DVI-I-1 pos: primary,left model: Samsung SyncMaster serial: H9NX842662 built: 2004 res: 1280x1024 hz: 60 dpi: 96 gamma: 1.2 size: 338x270mm (13.31x10.63") diag: 433mm (17") ratio: 5:4 modes: max: 1280x1024 min: 720x400 Monitor-2: VGA-1 pos: right model: Dell 1908FP serial: G434H87HRA2D built: 2008 res: 1280x1024 hz: 60 dpi: 86 gamma: 1.4 size: 376x301mm (14.8x11.85") diag: 482mm (19") ratio: 5:4 modes: max: 1280x1024 min: 720x400 OpenGL: renderer: AMD CEDAR (DRM 2.50.0 / 5.16.0-11.1-liquorix-amd64 LLVM 12.0.1) v: 3.3 Mesa 21.2.6 compat-v: 3.1 direct render: Yes
This is how inxi works, it's not negotiable
json output is meant for intermediate to expert users, same with xml. I
highly recommend outputting various features with --output xml
--output-file print
in order to see how it works. You'll see the mixture
of hashes and arrays that way much more clearly, and it is sorted, and you can
tell what is an array reference, and what is a hash reference. That's very
difficult to do with json raw, unless you put the json through a json decoder
with a real language then output it to screen, then it's fairly easy too, as
long as you have a way to output sorted json keys. For visualizing it, the xml
output is a lot easier.
Note that this is a feature, not a bug, no output would work in inxi without this feature, everything would become totally jumbled, and you can't remove those for xml/json output because then you'd have no way of knowing what is a parent or dhild or its sort order.
Json / xml is intended only for intermediate to advanced users, and no further support is offered, the data is there if you want it, if not, that's fine.
Basic conclusion
The use of the json output is 100% up to the end user. I can tell you however that some automated sys info generation tools online use the raw inxi output as far as I can tell, that is, they output the inxi command to a text file, and use that.
There's no way I can dumb down the output logic enough to make it 'user friendly' or 'trivial' to use, that would make my own job massively worse, and far more difficult, so inxi gives the data to you, and you are free to use it, or not use it, as you see fit.
If you are a decent programmer, you will have fun with this, if you can't figure it out, that's fine, just use the natural output of inxi and call it good.
Be part of the solution!
I put this item last deliberately, because nobody who didn't read the above material would reach down here, and thus, the only person to reach down here in general is a person who is going to actually implement a solution in their language of choice. This is the same reason I did not add an internal page navigation item.
If you have created a full solution in a specific languagge, and want to share it, I will put it up in the inxi-perl branch tools directory, in a parsers sub directory. Any solution must meet the following requirements:
- The code must be licensed with a free software license of your choosing.
- The code clearly indicates the language release version it was tested on. Ideally more than one version, which is a good way to avoid errors with using deprecating or deprecated or brand new language features.
- The code must work, that is, it can't just work on your subset of system, it has to always work with all possible output situations for data, including advanced RAID and LOGICAL, both of which can use recursive logic. Hint: you can build highly complex software RAID and LOGICAL block devices quite easily using virtual machines, like VirtualBox. This is how these features were developed in inxi, including creating insanely recursive structures in the software RAID/Logical block devices.
- It can be a simple parser that simply maps the json output to a data structure in the language of choice. This avoids many of the problems of using recursive data handlers
- The code must be well commented and clear, ideally explaining in the top comment header how to use it etc.
- If the code depends on a specific language feature from a specific language version, that must be indicated.
- The code is NOT a shell script, because that's useless for this feature.
- You have tested it extensively in diverse hardware/system scenarios, it is not a "oh it works on my system and now someneone else can figure out the hard parts I didn't do", that someone else is you, not me.
I will NOT accept incomplete or buggy solutions, the code has to work as intended, in all cases, including recursively. I will NOT spend any time beyond testing it actually works as intended fixing or maintaining these, since that would involve learning programming languages I don't wan to learn, or don't care about. But well crafted solutions that are seriously tested and are reliable should never require updates (except for python, of course, which loves breaking language features across releases). I will not maintain any such parser, but I will add it as a user supplied option.