The project team has addressed the concerns raised during the initial
discussion and produced an updated specification which I've placed in
the materials directory.  It's also included below.  Changes made:

* Made it clear that this case is specific to the dladm command
* Field separator is now ':' instead of '|'
* Escaping of field separator is only done if multiple fields are
  requested
* Clarified why a space was not used as a field separator
* Added proposed man page changes including examples

The timer for this case has been reset and will expire on June 24th,
2008.

   Overview
   ========

   This case proposes to revise the parsable output format for dladm(1M)
   to be both robust and easy to parse.

   Stability level is Committed.  Release Binding is Minor.


   Background
   ==========

   In general, it's helpful for building administrative scripts as well as
   test cases that there be some way to cause commands to issue output in
   a format that is stable and easy for scripts to parse.  While dladm(1M)
   currently provides a parsable output mode, it is not that easy to
   parse, especially from a shell:

   # dladm show-link -p
   LINK="e1000g0" CLASS="phys" MTU="1500" STATE="up" OVER=""
   LINK="e1000g1" CLASS="phys" MTU="1500" STATE="unknown" OVER=""
   LINK="e1000g2" CLASS="phys" MTU="1500" STATE="unknown" OVER=""
   LINK="e1000g3" CLASS="phys" MTU="1500" STATE="unknown" OVER=""

   Although one might think that "eval" could be used in the shell to
   access the set of values one line at a time, this has major pitfalls:

        * Each eval runs the risk possibly clobbering variables already in
          use by the script.  This means that any time a new field is
          added, there is small but very real potential to break any
          script that happened to use that field name as a local variable.

        * Use of eval presents a significant security risk: any command
          where a non-privileged user might gain control over any field's
          value makes eval as root (say, in an admin script) unsafe.

   Proposal
   ========

   We propose that parsable output employ a simple field separator scheme
   similar to what is already used by "zoneadm list -p":

         $ zoneadm list -p
         0:global:running:/::native:shared

   Further, we propose that the existing "-o" switch (which is used to
   enumerate fields to display) be required in parsable output mode.
   This ensure that we will be able to add new fields in the future
   without potentially breaking existing scripts.

   Note:

        * Fields with no value will be shown as being empty (see the
          example below), rather than "-" or "--", as might be used in
          normal output.

        * As before, headers will be omitted in parsable output mode.

        * Since it's possible that a field value could contain a
          literal ":", parsable output will escape literal ":" as
          "\:", and literal "\" as "\\".  Escaping will be done only
          when multiple values are requested via the -o option,
          allowing singletons to be used directly via var=`dladm ...`.
          As it happens, this escape format is already handled
          automatically by the "read" and "while read" shell
          constructs, ensuring that parsing remains simple when
          multiple values are requested.  Please refer to the examples
          in the proposed manual page changes.

   Output format examples:

     # dladm show-link -o link,over,state
     LINK       OVER    STATE
     e1000g0    --      up
     e1000g1    --      unknown
     e1000g2    --      unknown
     e1000g3    --      unknown

     # dladm show-link -p
     dladm: output field list (-o) required in parsable output mode

     # dladm show-link -p -o link,over,state
     e1000g0::up
     e1000g1::unknown
     e1000g2::unknown
     e1000g3::unknown

   Note that this is a change to a Committed interface, but it is a
   relatively safe change.  The Solaris 10 parsable output format was
   not usable and was already modified in Nevada build 83 to the
   format described in the Background section.  Changing the format
   again doesn't break anything new, and the project team is aware of
   the existing consumers of this format since they needed to be
   altered in build 83.

   Note also that space (" ") as a separator is not compatible with
   null representation of empty field values.  Shell read(1) treats
   sequential whitespace characters as a single separator.


   Man Page Changes
   ================

   Under all usages for:

       -p, --parsable

   Change text to:

     Displays output using a stable machine-parsable format.  The -o
     option is required with -p.  Refer to "Parsable Output Format"
     for more information.

   Under "Parsable Output Format", replace the text with the following:
   (somewhat lifted from the zoneadm man page):

     Many dladm subcommands have an option that displays output in a
     machine-parsable format.  The output format is one or more lines
     of colon (":") delimited fields.  Possible fields are specific to
     the subcommand used and are listed under the entry for the
     corresponding -o option.  Output includes only those fields
     requested via the -o option, in the order requested.

     When multiple fields are requested, any literal ":" characters
     will be escaped by a backslash ("\") before being output.
     Similarly, literal backslash characters will also be escaped
     ("\\").  This escape format is parsable by using shell read(1)
     functions with the environment variable IFS=: (see Example 11).
     Note that escaping is not done when only a single field is
     requested.


   Under EXAMPLES, add:

     Example 10, Using parsable output to capture a single field

     This example saves the mtu of link net0 to a variable named "mtu".

      # mtu=`dladm show-link -p -o mtu net0`

     Example 11, Using parsable output to iterate over links in a script

     This example script prints the state of each link on the system.

      # dladm show-link -p -o link,state | while IFS=: read link state; do
            print "Link $link is in state $state"
        done



Reply via email to