Today I stumbled upon the following challenge: I have some scripts that are supposed to receive 0 or 1 parameter. If the script receives 0 parameter, it returns a "usage" message and exit. I needed to change my scripts so that they can return a public interface specification without introducing new parameters (I have tenth of similar script and a mechanism calling them).

The basic idea is to set a global variable $SCRIPT_PUBLICINTERFACE to change the script behavior, so that an information-collecting script can get information from the scripts, without having to pass any parameter. This approach avoid changing significantly the structure of my scripts.

Here is my implementation for the scripts, followed by the "function" library.

#!/bin/bash
NPARAM=$#
# load library
source functions

function usageMessage(){
    echo "Script stoped with error: "$1
    echo "Script usage:"
    echo "  please set/unset variable SCRIPT_PUBLICINTERFACE to show/hidde publicInterface"
    echo "  example: "
    echo "   export SCRIPT_PUBLICINTERFACE=1"
    echo "   ./script.sh"
    echo "   unset SCRIPT_PUBLICINTERFACE"
    echo "   ./script.sh"
    exit 1
}

echo "The script is running and calling the usage function"
if [ $NPARAM -eq 0 ]; then
       usage "calling the usage function"
fi

Hereafter the 'function' library:

function usageMessage(){
         # default usageMessage. Overridden by user function
         echo "Script ${0##*/} received the error message:" $1
         echo "Please define a specific usageMessage function for this script."
}

function usage(){
        if [ -z "$SCRIPT_PUBLICINTERFACE" ]; then
            usageMessage "$1"
            return 0
         else
            printPublicInterface
            exit 1
         fi
}

function printPublicInterface(){
cat << EOF
<?xml version="1.0">
<dict>
...write here your xml file content...
</dict>
EOF

The user defines a "userMessage' function which contains the text to display in case of error, or if the script is called with no parameter. In case that the user forgets declaring such a function, there is a default definition in the library. The usage function checks if the global variable is set, and calls usageMessage or the function to output the public interface.