22

Background

Python scripts, for example, can have several "levels" of documentation via docstrings. What's neat about it, is that they can be defined at per-function levels, per-method levels, per-class levels, and most importantly (in the context of my question): per-file levels. For example, the top of the file may look like so:

#!/usr/bin/env python
"""
@brief  A script that does cool stuff.
"""

What's especially useful about this feature is that it's easy to extract and print at run-time.


Question

Do scripts support such a feature? i.e. is there a "standardized" approach to generating a file-level set of documentation (i.e. human-readable description of the purpose of the script, usage syntax, etc.; so that it's easy for another script to automatically parse/extract this information? My goal is to create several debug scripts that are self-documenting, and if there's already a standard/de-facto-best way to do this, I'd like to avoid re-inventing the wheel.

Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
Cloud
  • 18,753
  • 15
  • 79
  • 153
  • 1
    Short answer: no, `bash` itself has nothing. That makes this a question about which 3rd-party tools that might follow some convention, which makes it off-topic. – chepner Mar 01 '19 at 17:00

5 Answers5

7

The "File Header" section of Google's Shell Style Guide is one way to add a 'docstring' to your bash scripts.

Basically, the answer is to use #, rather than quotes like you would with Python.

Nuno André
  • 4,739
  • 1
  • 33
  • 46
Deena
  • 71
  • 1
  • 4
7

You can do this for Bash easily, it is a little more tricky if you need to ensure compatibility with POSIX only shells like /bin/sh or primarily busybox systems like Alpine.

The Linux Documentation Project has some great examples.

http://tldp.org/LDP/abs/html/here-docs.html

Yet another twist of this nifty trick makes "self-documenting" scripts possible.

Example 19-12. A self-documenting script

#!/bin/bash
# self-document.sh: self-documenting script
# Modification of "colm.sh".

DOC_REQUEST=70

if [ "$1" = "-h"  -o "$1" = "--help" ]     # Request help.
then
  echo; echo "Usage: $0 [directory-name]"; echo
  sed --silent -e '/DOCUMENTATIONXX$/,/^DOCUMENTATIONXX$/p' "$0" |
  sed -e '/DOCUMENTATIONXX$/d'; exit $DOC_REQUEST; fi


: <<DOCUMENTATIONXX
List the statistics of a specified directory in tabular format.
---------------------------------------------------------------
The command-line parameter gives the directory to be listed.
If no directory specified or directory specified cannot be read,
then list the current working directory.

DOCUMENTATIONXX

if [ -z "$1" -o ! -r "$1" ]
then
  directory=.
else
  directory="$1"
fi  

echo "Listing of "$directory":"; echo
(printf "PERMISSIONS LINKS OWNER GROUP SIZE MONTH DAY HH:MM PROG-NAME\n" \
; ls -l "$directory" | sed 1d) | column -t

exit 0

Using a cat script is an alternate way of accomplishing this.

DOC_REQUEST=70

if [ "$1" = "-h"  -o "$1" = "--help" ]     # Request help.
then                                       # Use a "cat script" . . .
  cat <<DOCUMENTATIONXX
List the statistics of a specified directory in tabular format.
---------------------------------------------------------------
The command-line parameter gives the directory to be listed.
If no directory specified or directory specified cannot be read,
then list the current working directory.

DOCUMENTATIONXX
exit $DOC_REQUEST
fi

A slightly more elegant example using functions to handle the documentation and error messages.

#!/bin/sh

usage() {
cat << EOF
Usage: 
  $0 [-u [username]] [-p]
  Options:
    -u <username> : Optionally specify the new username to set password for.  
    -p : Prompt for a new password.
EOF
}

die() {
  echo
  echo "$1, so giving up.  Sorry."
  echo
  exit 2
}

if [ -z "$USER" ] ; then
  die "Could not identify the existing user"
fi

if $PSET ; then
  passwd $USER || die "Busybox didn't like your password"
fi

https://github.com/jyellick/mficli/blob/master/util/changecreds.sh

dragon788
  • 3,583
  • 1
  • 40
  • 49
4

There is no standard for docstrings for bash. It's always nice to have man pages though (eg. https://www.cyberciti.biz/faq/linux-unix-creating-a-manpage/), or info pages (https://unix.stackexchange.com/questions/164443/how-to-create-info-documentation).

thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • Excellent! Thank you. While I would have preferred being able to have the documentation "baked in" to the script, this will suit my use case just fine. – Cloud Mar 01 '19 at 17:36
0

I proposed a method for how to do bash docstrings in a blog post.

In short, use a non-executing function __docstring__(), and write a help commands that find all of these to print a help screen.

build() {
    __docstring__() {
        echo """<params>

        Build and work on stuff

        -j <core> - number of cores
        """
    }

    : # << your build implementation here >>
}
Dan Aloni
  • 3,968
  • 22
  • 30
0

You can use the : (null) built-in for bash functions loaded into your environment from a .bashrc-style include.

$ declare -f my_function
my_function() {
    : My function does this and that
    echo "foo"
}

$ my_function
foo
Matt Kneiser
  • 1,982
  • 18
  • 23