SG3_UTILS_JSON(8)

🌸 NAME 🌸

This is the SG3_UTILS_JSON(8) page, sitting pretty in the SG3_UTILS manual β€” and bestie, it's literally just sg3_utils_json: JSON output for some sg3_utils utilities ✨


πŸŽ€ SYNOPSIS πŸŽ€

sg_* --json[=JO] [--js-file=JFN] [OTHER_OPTIONS] [DEVICE]

πŸ¦‹ DESCRIPTION πŸ¦‹

Okay so first things first: sg3_utils is a whole package of utilities that send SCSI commands to the DEVICE you give them, and they do it through a SCSI pass through interface that your host operating system provides. Some of these utilities β€” mainly the ones decoding structured data that SCSI commands return (think sg_vpd, that kind of vibe) β€” can optionally give you JSON output instead of the plain text output. Default stays plain text though. No cap. πŸ’…

JavaScript Object Notation (JSON) is an open standard file format, used for swapping data between programs, including across a network. Peep https://en.wikipedia.org/wiki/JSON if you want the lore. JSON comes in many flavours, and this one uses the json-builder C implementation found at https://github.com/json-parser/json-builder β€” which implements four simple JSON data types: string, integer, boolean and null. Its other data types are the JSON object and JSON array. 🫢

This project uses the 'snake_case' convention for JSON object names: all in lower case (ASCII) letters or numerals, with individual words joined with a single underscore (e.g. "starting_lba"). There should be no leading or trailing underscore characters. Repeated underscores are abridged to a single underscore. The json-builder library uses the SPDX-License-Identifier: BSD-2-Clause, which is the same license as the bulk of the utilities in the sg3_utils package. ✨

The json-builder library is relatively lightweight (700 lines of C code) and is 'hidden' fully within the sg3_utils library, so its function interface and data types are not available (directly) to the utilities in the sg3_utils package. That's literally why the json-builder interface (a file named sg_json_builder.h) lives in the lib directory and not in the include directory. As presented on github, json-builder shares some header files with its companion json-parser. The author has modified the json-builder header to include what's needed from the json-parser header so that only the builder gets built and not the parser. The parser could be added later, but currently there seems to be no need for it. πŸ’€

The user interface to JSON functionality in the sg3_utils package is heavily based on what has been done by Christian Franke and others in smartctl, a utility in the smartmontools package for getting S.M.A.R.T. information from disks (and other storage devices). Obsessed, honestly. πŸ‘‘

This manpage discusses the --json[=JO] and --js-file=JFN command line options. Notice that the argument to --json is itself optional. In its shorter form the --json option may either be -j or -J (lower case preferred if not already in use). The shorter form may also take an argument, but an "=" must precede the JO argument with no spaces either side of the "=". ⭐

Some care has been taken with quotes in this manpage, so listen up: double quotes are used around JSON object names, and single quotes are used for all other purposes. πŸŽ€


🌈 ENVIRONMENT VARIABLES 🌈

  • SG3_UTILS_JSON_OPTS β€” lets the user override the default values of the JO settings. Those settings can again be overridden by the command line --json[=JO] option. If the string associated with SG3_UTILS_JSON_OPTS cannot be parsed, this error message gets sent to stderr: 'error parsing SG3_UTILS_JSON_OPTS environment variable, ignore'. πŸ™ˆ

πŸ’œ OPTIONS πŸ’œ

Since the argument to --json[=JO] is optional, in the shorter form there can be no space(s) between the option and its argument. Periodt. ✨

  • -j[=JO], --json[=JO] β€” JO is a string of zero or more characters whose order is not significant, apart from the negation characters ('-' is preferred). The negation character must appear immediately before the (boolean) feature it is toggling. In the short form the option letter may be something other than -j if that letter has already been used (-J is preferred next). For example, the sg_ses utility uses -j for its 'join' operation. Also, since the argument to the short form option is itself optional, there can be no spaces between the short form option, the "=", and JO, if it is given. Some short form examples: '-jl' requests JSON output (with no argument option) and whatever the '-l' short option means in the invoked utility; '-j=h' requests JSON output with some integers additionally rendered as JSON strings of hex. πŸ”₯
  • -J, --js-file=JFN β€” output is in JSON format and it is sent to a file named JFN. If that file exists then it is truncated. By default, the JSON output is sent to stdout. When this option is given, the --json[=JO] option is implied and need not be given. The --json[=JO] option may still be needed to set the JO parameter to non-default values. The short option may be something other than -J if that short option was already in use. πŸ’…

✨ JSON CONTROL CHARACTERS ✨

ok so here's the tea: every JO string is literally just made up of zero or more of these little JSON control characters. that's it. that's the whole vibe. pick your faves πŸ’…

  • 0 β€” if you're pretty printing JSON output, tab to 2 spaces.
  • 2 β€” if you're pretty printing JSON output, tab to 2 spaces.
  • 4 β€” if you're pretty printing JSON output, tab to 4 spaces. this is the default tab setting for pretty printing JSON, bestie.
  • 8 β€” if you're pretty printing JSON output, tab to 8 spaces.
  • - β€” the negation character. it toggles the (boolean) sense of the control character that comes right after it. iconic little hater behavior 🫢
  • e β€” this is a boolean control character for "exit status". if it's active, an "exit status" field gets placed at the end of the JSON output. the integer value of that field is the Unix exit status value that gets returned to the operating system when this utility exits. the value of 0 is a good exit (i.e. no errors detected). this boolean control character is default on (true). πŸ‘‘
  • h β€” this is a boolean control character for 'hexadecimal'. so many values associated with SCSI are best (or at least, historically, have been) viewed in hexadecimal, while JSON output prefers decimal integers (assumed to have a maximum size of 64 bits, signed). the maximum size of most SCSI fields is 64 bit unsigned. also some SCSI fields are masks, which are best viewed in hex. when this control character is active, most (non-trivial) fields that have an integer value instead receive a sub-object containing at least an "i" field with the integer value and a "hex" field with the corresponding hex value in a JSON string. that hex string has no hex decorations (i.e. no leading '0x' nor trailing 'h'). this boolean control character is default off (false).
  • k β€” this is a boolean control character for finer control of non-pretty printed JSON output. if the 'p' control character is set on (true) then this option has no effect. if the 'p' control character is set off (false) and this control character is set off (false), then the single line JSON output contains some spaces for readability. if the 'p' control character is set off (false) and this control character is set on (true), then the JSON single line JSON output is 'packed', removing all unnecessary spaces. this boolean control character is default off (false).
  • l β€” this is a boolean control character controlling whether lead-in fields are output. lead-in fields are at the start of the JSON output and include the "json_format_version" and "utility_invoked" sub-objects. the "utility_invoked" sub-object includes "name", "version_date" string fields and a JSON array named "argv" with an entry for each command line argument. if the o control character is also active, then, if available, the non_JSON output (i.e. the original, 'plain text' form) is placed in an array called "plain_text_output" with one element per line of 'normal' output. this boolean control character is default on (true).
  • n β€” this is a boolean control character for "name_extra". it's used to provide additional information about the name that it's a sub-object of. the most common usage is to spell out an abbreviated name (e.g. a T10 name like 'SKSV' to 'Sense Key Specific Valid'). another use is to note that a T10 field is obsolete and in which T10 standard it first became obsolete. also, if the named field's value is a physical quantity where the unit is unclear (e.g. a timeout) then "name_extra" can state that (e.g. 'unit: millisecond'). only some fields have associated "name_extra" data. this boolean control character is default off (false).
  • o β€” this is a boolean control character controlling whether normal (i.e. non-JSON) lines of output are placed in a JSON array (one element per line of normal output) within the utility_invoked subject (see control character l). the name of the array is "plain_text_output". this control character is active even if the lead-in fields control character (l) is negated. this boolean control character is default off (false).
  • p β€” this boolean control character controls whether the JSON output is 'pretty printed' or sent in a relatively compact stream suitable for more efficient transmission over a communications channel. the pretty printed form of output has one JSON name with its associated integer, string or boolean value per line; and one array element per line. JSON objects and arrays that have an associated JSON object as their value have their name on a separate line. these lines are indented with the current tab setting to indicate the level of nesting. basically the pretty printed form is for human consumption. there are two forms of non-pretty printed output, see the 'packed' control character ['k']. this boolean control character is default on (true). 🌸
  • s β€” this boolean control character controls whether T10 field values that have a defined meaning are broken out with an added JSON sub-object usually named "meaning". when active, the field name has a sub-object that contains at least an "i" field with the integer value of the field and a JSON string object, usually named "meaning", with a string that corresponds to the T10 defined meaning of the value in the "i" field. this boolean control character is default on (true).
  • v β€” this is an integer control character that controls the amount of debug output. it can be given multiple times to increase the level of JSON debug verbosity in the output. note that this verbose control character is JSON specific, while the --verbose option (short form: -v often repeated: -vvv) that most utilities support is more general. this integer control character is set to 0 by default.

πŸ¦‹ OUTPUT PROCESSING πŸ¦‹

ok so the default stays the same for all utilities that support the --json option, namely the decoded information is sent to stdout in plain text form. errors get reported to stderr and may cause the early termination of a utility (e.g. a command line option syntax error). 😭

when the --json option is given and no errors are detected, then only JSON is normally sent to stdout. as the SCSI response is parsed, a JSON representation is built as a tree in memory. after all other actions (perhaps apart from the final exit status report), that JSON tree is 'dumped' to stdout. this means if there's any non-JSON output sent to stdout, it will appear before the JSON output. no cap.

if the 'o' control character is in the JO argument to the --json option, then the former plain text output is placed in a JSON array named "plain_text_output" within a JSON object named "utility_invoked". each line of the former 'plain text' output is placed in its own element of the JSON array.

a JSON tree is built in memory as the utility parses the data returned from the SCSI device (e.g. sg_vpd parsing a VPD page returned from a SCSI INQUIRY command). SCSI 'list's become JSON named arrays (e.g. in the Device Identification VPD page there is a 'Designation descriptor list' that becomes a JSON array named "designation_descriptor_list"). literally so satisfying to watch 🧚

at the completion of the utility, that JSON tree is 'measured' taking into account the form of output (i.e. pretty-printed, single line or packed single line). for the pretty-printed JSON output, the size of each indentation in spaces is also given (i.e. the tab width). the JSON is then output to a single C string, then sent to stdout. if a NULL character (ASCII zero and C string terminator) somehow finds its way into a field that should (according to the spec) be space padded, then the JSON output may appear truncated. πŸ’€ so watch out for that one.

note that this JSON processing means that if a utility is aborted for whatever reason, then no JSON output will appear. with the normal, plain text output processing, some output may appear before the utility aborts in such bad situations.

🌈 BOOLEAN OR 0/1 🌈

in general, the JSON generated by this package outputs 1 bit SCSI fields as the integer value 0 (for false) and 1 (for true). this follows the SCSI convention, which predates the common use of boolean. also SCSI reserved fields are output as the integer value 0. extensions to SCSI commands and associated data descriptors typically use parts of commands or data descriptors that were previously reserved. history is wild fr fr.


πŸ’œ INTERACTION WITH OTHER OPTIONS πŸ’œ

as stated above, the default output is in plain text form using 7 bit ASCII. the --json[=JO] option is designed to be an alternative to that plain text form. there are other alternative output formats, such as the response output as a hexadecimal sequence of bytes, or in 'raw' binary output; both of those take precedence over the --json[=JO] option. other specialized output formats (e.g. 'sg_inq --export') will usually take precedence over JSON output. πŸ‘‘

when the --raw option is used together with the --inhex=FN option, only the data input to the utility is interpreted as binary. so the output format defaults to plain text form, and thus can be changed to JSON if the --json[=JO] option is also used.

there is typically only one form of JSON output, so options like --brief and --quiet are ignored in the JSON output. in some cases (i.e 'sg_inq --descriptors') the JSON output is expanded. slay.

🏷️ NAMING: SCSI, JSON, LINUX PSEUDO FILE SYSTEM

okay so real talk: there is no perfect match for how commands, fields, objects and files get named across these three systems. Like, none. It's giving three besties who all picked different aesthetics πŸ’…

SCSI literally dates from a period when there were still 6 bit character sets with no lower case letters in use β€” imagine 😭. So SCSI commands and field names are all upper case, with a space used as a separator.

JSON prefers "CamelCase", where the first letter of each word is capitalized, so you don't need a space as a separator. But lots of JSON representations (this one included, bestie) ignore JSON's preference and go for "snake_case" instead.

Why tho? Because most Unix based pseudo file systems use lower case, periodt. And also β€” spaces inside file names create extra complexity when you're using basic Unix commands and scripting, so they're genuinely best avoided. No cap.

In Linux, sysfs is a very important pseudo file system for communicating real time information between hardware drivers and the user space. Utilities like lsblk and lsscsi do their data-mining inside sysfs. The vast majority of filenames in sysfs use "snake_case", but there are a few exceptions where ':' and even embedded spaces show up πŸ™ˆ. Also worth noting: Unix user commands, system commands and libraries have no embedded spaces in their names, and upper case letters are extremely rare.

Another issue is case sensitivity: "CamelCase" and "camelcase" are confusing filenames that refer to different files in most Unix file systems, but refer to the same file in Windows file systems like FAT and NTFS πŸ’€. Now add in the possibility of non-ASCII Unicode characters and searching a JSON object for a name match could become a whole nightmare.

So the choice is this: JSON object names made up of a string of characters restricted to lower case ASCII alphabetical characters, the digits, and underscore β€” only 26+10+1 different characters allowed. It's a compromise πŸŽ€. A compromise that favours simplicity of searching while restricting the freedom of object naming. It follows Unix (Linux) file naming conventions, iykyk.

Also worth mentioning: all these utilities in this package use UTF-8. So if data from another system is in UTF-16 or UTF-32 format, you can convert it to UTF-8 with the iconv utility. slay ✨


🚨 ERRORS

No attempts have been made to translate errors into JSON form, apart from the final "exit_status" JSON object, where a value of 0 means 'no errors'. Exit status values indicating a problem range from 1 to 255.

The sg_decode_sense utility will parse SCSI sense data into JSON form if you ask it to. So if another utility is failing with a sense data report (most often seen when the --verbose option is used), that sense data (in hex bytes) could be cut-and-pasted onto the command line following 'sg_decode_sense -j ' which should then render that sense data in JSON. cute little rescue mission fr fr 🫢

Otherwise, when an error is detected while JSON output is selected, the error message is sent to stderr in plain text form. Typically once an error is detected the utility will exit, first dumping the JSON in-memory tree as discussed above, and a non-zero exit status will be set. The JSON output will be well formed but missing any fields or list elements following the point that the error was detected.

so like… it's still valid JSON, it's just missing its ending. think of it as a sentence that trails off mid- 😭

The summary is that when JSON output is selected and an error occurs, each utility will process the error the same way as it would if JSON output had not been selected. In most cases error messages, in plain text form, are sent to stderr.


✍️ AUTHORS

Written by Douglas Gilbert. Some utilities have been contributed, see the CREDITS file and individual source files (in the 'src' directory). iconic behaviour honestly πŸ‘‘


πŸ› REPORTING BUGS

Report bugs to <dgilbert at interlog dot com>. don't be shy, they wanna hear it πŸ’Œ


Copyright Β© 2022-2026 Douglas Gilbert

This software is distributed under the GPL version 2 or the BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


πŸ‘€ SEE ALSO


and that's the whole page bestie, you made it to the end, so proud of you πŸŒˆπŸ’– this was sg3_utils-1.49, dated 2026-07-18 β€” go forth and JSON responsibly βœ¨πŸ¦‹πŸŽ€

πŸ“¦ where this page comes from