May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Neatbash -- a simple bash prettyprinter 

  Nikolai Bezroukov, 2019,   Licensed under Perl Artistic license
Version 0.9 (Sept 3, 2019)

Pretty printer Neatbash can be called a "fuzzy" pretty-printer. If does not perform full lexical analysis (which for bash is impossible  as BASH does not have lexical level defined). Instead it relies on analysis of a limited context of each line (prefix and suffix) to "guess" correct nesting level.  It does not perform any reorganization of the text other then re-indentation.

  For reasonable bash style typically found in production scripts the results are quite satisfactory. Of course, it will not work for compressed or obscured code.

This is a relatively novel approach as typically prettyprinter attempt to implement full lexical analysis of the language with some elements of syntax analysis, see for example my (very old) NEATPL pretty printer (  ) -- one of the first first program that I have written that got widespread use,  or Perltidy.

The main advantage is that such approach allows to implement pretty capable pretty printer is less then 500 lines of Perl source code with around 200 lines implementing  the formatting algorithm. Such small scripts are more maintainable and have less chances to "drop dead" and became abandonware after the initial author lost interests and no longer supports the script.

Neatperl does not depends on any non-standard Perl modules and it's distribution consists just of two items: the script itself and the readme file.  This is an advantage as installing Perl modules in corporate environment often is not that simple and you can run into some bureaucratic nightmare.  also with  many modules used you always risk compatibility hell. It is sad that Perl does not have zipped format as jar files for Java which allow to package the program with dependencies as a single file. but we have what we have

Another huge advantage is the this is  a very safe approach, which normally does not (and can not) introduces any errors in bash code with the exception of indented here lines which might be "re-indented" based on the current nesting.  As BASH has no defined lexical level and its parsing is a very complex task equivalent to writing a syntax analysis part of bash interpreter. As such can never be guaranteed to be  completely correct. Which means that "fuzzy" prettyprinter approach  this is safer approach for such language but even it can mange some  parts of the script such as HERE strings in case of some "too inventive" delimiters used.   You can be sure that no errors are injected by the formatter into the script.

But there is no free lunch, and such limited context approach means that sometimes (rarely) the nesting level can be determined incorrectly.  There also might be problem with multiline string literals including HERE literals that have non zero fixed indent that can't be changed (HERE stings with zero indent are safe)

To correct this situation three pseudo-comments (pragmas)  were introduced using which you can control the formatting and correct formatting errors. All pesudocomments should start at the beginning of the line. No leading spaces allowed.

 Currently Neatbash allows three types of pseudo-comments:

  1. Switching formatting off and on for the set of lines. This idea is similar to HERE documents allowing to skip portions of the script which are too difficult to format correctly. One example is a here statement with indented lines when re-indenting them to the current nesting level (which is the default action of the formatter)  is undesirable. 
  2. Correcting nesting level if it was determined incorrectly. The directive is "#%NEST" which has  several forms (more can be added if necessary ;-): 

For example, if neatbash did not recognize correctly the  point of closing of a particular control structure you can close it yourself with the directive





Also you can arbitrary increase and decrease indent with this directive

As Neatbash maintains stack of control keywords it reorganize it also produces some useful diagnostic messages, which in many cases are more precise then  bash diagnostics.

For most scripts Neatbash is able to determine that correct nesting level and proper indentation. Of course, to be successful, this approach requires a certain (very reasonable) layout of the script. the main requirement is that multiline control statements should start and end on a separate line. They can not have preceding statements on the same line. For example

a=$1; if (( $a > $b )) ; then
max=$a; else max=$b; fi
but one liners (control statements which start and end on the same line) are acceptable
a=$1; if (( $a > $b )) ; then max=$a; else max=$b; fi

While any of us saw pretty perverted formatting style in some scripts this typically is an anomaly in production quality scripts and most production quality scripts display very reasonable control statements layout, the one that is expected by this pretty printer. 

But again that's why I called this pretty printer "fuzzy"

For any script compressed to eliminate whitespace this approach is not successful


neatbash [options] [file_to_process]
neatbash -f [other_options] [file_to_process] # in this case the text will be replaced with formatted text, 
                                              # backup will be saved in the same directory
cat file | neatbash -p [other_options] > formatted_text # invocation as pipe



  1st -- name of the file to be formatted

Top Visited
Past week
Past month


Old News ;-)

[Sep 02, 2019] Uploaded to GitHub

This is still raw version (0.9, so it is still beta, but usable ). It works for all my scripts and script by other authors (mainly from SGE), that I tested

Recommended Links

Google matched content

Softpanorama Recommended

Top articles