-
Notifications
You must be signed in to change notification settings - Fork 1
UnixShellTutorial
This tutorial will demonstrate how to use the program interface definition framework to write a Bash or Zsh shell script where usage and command line option parsing is automatically generated.
- [Creating a shell script](#Creating a shell script)
- [Step 1. Defining the options](#Step 1. Defining the options)
- [Step 2. Write your code](#Step 2. Write your code)
- [Step 3. A little glue file](#Step 3. A little glue file)
- [Step 4. Build](#Step 4. Build)
- [Step 5. Run!](#Step 5. Run!)
- [Step 6. Beyond the bash](#Step 6. Beyond the bash)
- [Auto complete](#Auto complete)
The first step is to describe the program options in a XML file. The XML elements have to follow the program
XML Schema.
samples/miniapp/miniapp.xml
#!xml
<?xml version="1.0" encoding="utf-8"?>
<prg:program version="2.0" xmlns:prg="http://xsd.nore.fr/program">
<prg:name>miniapp</prg:name>
<prg:version>1.0</prg:version>
<prg:options>
<prg:switch>
<prg:databinding>
<prg:variable>displayHelp</prg:variable>
</prg:databinding>
<prg:names>
<prg:long>help</prg:long>
<prg:short>h</prg:short>
</prg:names>
</prg:switch>
<prg:argument>
<prg:databinding>
<prg:variable>arg</prg:variable>
</prg:databinding>
<prg:names>
<prg:long>some-arg</prg:long>
<prg:short>a</prg:short>
</prg:names>
</prg:argument>
</prg:options>
</prg:program>
You can use any editor to write this file but an XML editor with auto-completion and XML Schema support will greatly increase the writing speed.
Let's write a little and useless (Bash) shell script samples/miniapp/miniapp.body.sh
## Just list the command line arguments
echo "program was called with ${#} argument(s): ${@}"
i=1
while [ ${i} -le $# ]
do
echo $i:${!i}
i=$(expr $i + 1)
done
## Parsing the command line
if ! parse "${@}"
then
parse_displayerrors
exit 1
fi
# parse and parse_displayerrors functions will be generated automatically
## Let's see what we get
echo "Sub command: ${parser_subcommand}"
echo "Values (${#parser_values[*]})"
for v in "${parser_values[@]}"
do
echo " - ${v}"
done
# ${parser_subcommand}, ${parser_values} are defined by the parser
# - ${parser_subcommand} contains the name of the sub command (if any)
# - ${parser_values} is an array of anonymous values (command line arguments which are not options nor option arguments)
## Display program usage if asked
${displayHelp} && usage
# ${displayHelp} is defined automatically when reading your XML file
# It will be set to true if the --help option is given on the command line
# usage function is also generated automatically.
if [ ! -z "${arg}" ]
then
echo "You set the --some-arg option to ${arg}"
fi
# Like ${displayHelp}, ${arg} is automatically defined and its value set if the
# command line contains --some-arg "arg_value"
exit 0
To glue the XML definition with the bash code, We will write a small XML file (a .xsh
)
samples/miniapp/miniapp.xsh
#!xml
<?xml version="1.0" encoding="UTF-8"?>
<sh:program interpreter="/usr/bin/env bash"
xmlns:prg="http://xsd.nore.fr/program"
xmlns:sh="http://xsd.nore.fr/bash"
xmlns:xi="http://www.w3.org/2001/XInclude">
<sh:info>
<xi:include href="miniapp.xml" />
</sh:info>
<sh:code>
<xi:include href="./miniapp.body.sh" parse="text" />
</sh:code>
</sh:program>
#!bash
${NSXML_PATH}/ns/sh/build-shellscript.sh -x miniapp.xml -s miniapp.xsh -o miniapp.sh
This command line tool will generate the usage and option parsing code and append your code. The result can be found here: samples/miniapp/miniapp.sh
#!bash
./miniapp.sh --help --some-arg "Bleeeh Blaaah"
You should try to type invalid options or forget the --some-arg
argument to see what's happen.
To get a bash auto-completion command file, use the bashcompletion.xsl
stylesheet to transform the option specification file
#!bash
xsltproc -o miniapp-autocomplete.inc.sh --stringparam prg.bash.completion.programFileExtension ".sh" ${NS_XML_PATH}/ns/xsl/program/${SCHEMA_VERSION}/bashcompletion.xsl miniapp.xml
Then, include the generated file in your current environment
#!bash
. miniapp-autocomplete.inc.sh
And try typing
#!bash
./miniapp.sh -<TAB>
The shell will propose...
#!bash
$ ./miniapp.sh -
-a -h --help --some-arg
See the Bash auto-complete file generation for more details.