Argbash (https://argbash.io) is a
bash code generator that can assist you in writing scripts that accept arguments.
You declare arguments that your script should use in a few lines and then, you run
Argbash on those declarations to get a parsing code that can be used on all platforms that have
bash (Linux, macOS, MS Windows, …).
You can have your parsing code in the script, you can have
Argbash to help you to use it as a
bash library, or you can generate the library yourself and include it yourself too, it’s up to you.
A basic template generator
argbash-init is part of the package, and you can get started with it in a couple of seconds.
Argbash is free and open source software, you are free to use it, share it, modify it and share the modifications with the world, since it is published under the 3-clause BSD linense.
|Copyright:||2014–2019, Matěj Týč|
Both you and your users need:
Only you need those on the top:
Argbashmakes use of the
sed, etc. (if you have
autoconf, you probably have those already)
In a nutshell, using
Argbash consists of these simple steps:
- You write (or generate) a simple template of your script based on arguments your script is supposed to accept.
- You run the
argbashscript (located in the package’s
bindirectory) on it to get the fully functional script.
Eventually, you may want to add/remove/rename arguments your script accepts.
In that case, you just need to edit the script — you don’t need to repeate the two steps listed above!
Why? It is so because the script retains the template section, so if you need to make adjustments to the template, you just edit the template section of the script and run
argbash on top of the script to get it updated.
How to use
You can either
Generating a template¶
Argbash features the
argbash-init script that you can use to generate a template in one step.
Assume that you want a script that accepts one (mandatory) positional argument
positional-arg and two optional ones
In other words, we want to support these arguments:
--optionthat accepts one value,
--no-printthat doesn’t accept any value, and
- an argument named
positional-argthat we are going to refer to as positional that must be passed and that is not preceeded by options (such as
argbash-init and as the desired result is a script, we directly pipe the output of
bin/argbash-init --pos positional-arg --opt option --opt-bool print - | ../bin/argbash -o script.sh -
Let’s see what the auto-generated script can do!
./script.sh -h <The general help message of my script> Usage: ./script.sh [--option <arg>] [--(no-)print] [-h|--help] <positional-arg> -h, --help: Prints help
./script.sh --print --option opt-value pos-value Value of --option: opt-value 'print' is on Value of 'positional-arg': pos-value
We didn’t have to do much, yet the script is pretty capable.
Writing a template¶
Now, let’s explore more advanced argument types on a trivial script that accepts some arguments and then prints their values. So, let’s say that we would like a script that produces the following help message:
This is a minimal demo of Argbash potential Usage: ../resources/examples/minimal.sh [-o|--option <arg>] [--(no-)print] [-h|--help] [-v|--version] <positional-arg> <positional-arg>: Positional arg description -o, --option: A option with short and long flags and default (default: 'boo') --print, --no-print: A boolean option with long flag (and implicit default: off) (off by default) -h, --help: Prints help -v, --version: Prints version
Then, it means that we need following arguments:
- One mandatory positional argument. (In other words, an argument that must be passed and that is not preceded by options)
- Four optional arguments:
--optionthat accepts one value,
--no-printthat doesn’t accept any value — it either is or isn’t specified,
--versionthat also doesn’t accept any value and the program is supposed just to print its version and quit afterwards, and finally
--helpthat prints a help message and quits afterwards.
Therefore, we call
argbash-init like we did before:
bin/argbash-init --pos positional-arg --opt option --opt-bool print minimal.m4
Next, we edit the template so it looks like this:
#!/bin/bash # m4_ignore( echo "This is just a script template, not the script (yet) - pass it to 'argbash' to fix this." >&2 exit 11 #)Created by argbash-init v2.8.0 # ARG_OPTIONAL_SINGLE([option], o, [A option with short and long flags and default], [boo]) # ARG_OPTIONAL_BOOLEAN([print], , [A boolean option with long flag (and implicit default: off)]) # ARG_POSITIONAL_SINGLE([positional-arg], [Positional arg description], ) # ARG_DEFAULTS_POS # ARG_HELP([This is a minimal demo of Argbash potential]) # ARG_VERSION([echo $0 v0.1]) # ARGBASH_SET_INDENT([ ]) # ARGBASH_GO
The body of the script (i.e. lines past the template) is trivial, but note that it is enclosed in a pair of square brackets. They are “hidden” in comments and not seen by the shell, but still, they have to be there for the “use the script as a template” feature to function.
# [ <-- needed because of Argbash if [ "$_arg_print" = on ] then echo "Positional arg value: '$_arg_positional_arg'" echo "Optional arg '--option' value: '$_arg_option'" else echo "Not telling anything, print not requested" fi # ] <-- needed because of Argbash
We generate the script from the template:
bin/argbash minimal.m4 -o minimal.sh
Now we launch it and the output is good!
./minimal.sh posi-tional -o opt-ional --print Positional arg value: posi-tional Optional arg --option value: opt-ional
If something still isn’t totally clear, take look at the Examples section.
Please read this carefully.
The square brackets in your script have to match (i.e. every opening square bracket
[has to be followed at some point by a closing square bracket
There is a workaround — if you need constructs s.a.
red=$'\e[0;91m', you can put the matching square bracket behind a comment, i.e.
red=$'\e[0;91m' # match square bracket: ].
This limitation does apply only to files that are processed by
argbash— you are fine if you have the argument parsing code in a separate file and you don’t use the
INCLUDE_PARSING_CODEmacro. You are also OK if you use argbash-init in the decoupled mode.
The generated code generally contains bashisms as it relies heavily on
basharrays to process any kind of positional arguments and multi-valued optional arguments. That said, if you stick with optional arguments only, a POSIX shell s.a.
dashshould be able to process the
Argbash-generated parsing code.