The ability to accept and handle command line arguments is very important when writing Guile scripts to solve particular problems, such as extracting information from text files or interfacing with existing command line applications. This chapter describes how Guile makes command line arguments available to a Guile script, and the utilities that Guile provides to help with the processing of command line arguments.
When a Guile script is invoked, Guile makes the command line arguments
accessible via the procedure
command-line, which returns the
arguments as a list of strings.
For example, if the script
#! /usr/local/bin/guile -s !# (write (command-line)) (newline)
is saved in a file `cmdline-test.scm' and invoked using the command
./cmdline-test.scm bar.txt -o foo -frumple grob, the output
("./cmdline-test.scm" "bar.txt" "-o" "foo" "-frumple" "grob")
If the script invocation includes a
-e option, specifying a
procedure to call after loading the script, Guile will call that
(command-line) as its argument. So a script that
-e doesn't need to refer explicitly to
in its code. For example, the script above would have identical
behaviour if it was written instead like this:
#! /usr/local/bin/guile \ -e main -s !# (define (main args) (write args) (newline))
(Note the use of the meta switch
\ so that the script invocation
can include more than one Guile option: See section The Meta Switch.)
These scripts use the
#! POSIX convention so that they can be
executed using their own file names directly, as in the example command
./cmdline-test.scm bar.txt -o foo -frumple grob. But they
can also be executed by typing out the implied Guile command line in
full, as in:
$ guile -s ./cmdline-test.scm bar.txt -o foo -frumple grob
$ guile -e main -s ./cmdline-test2.scm bar.txt -o foo -frumple grob
Even when a script is invoked using this longer form, the arguments that
the script receives are the same as if it had been invoked using the
short form. Guile ensures that the
arguments are independent of how the script is invoked, by stripping off
the arguments that Guile itself processes.
A script is free to parse and handle its command line arguments in any
way that it chooses. Where the set of possible options and arguments is
complex, however, it can get tricky to extract all the options, check
the validity of given arguments, and so on. This task can be greatly
simplified by taking advantage of the module
which is distributed with Guile.
(ice-9 getopt-long) module exports two procedures:
getopt-longtakes a list of strings -- the command line arguments -- and an option specification. It parses the command line arguments according to the option specification and returns a data structure that encapsulates the results of the parsing.
option-refthen takes the parsed data structure and a specific option's name, and returns information about that option in particular.
To make these procedures available to your Guile script, include the
(use-modules (ice-9 getopt-long)) somewhere near the
top, before the first usage of
This subsection illustrates how
getopt-long is used by presenting
and dissecting a simple example. The first thing that we need is an
option specification that tells
getopt-long how to parse
the command line. This specification is an association list with the
long option name as the key. Here is how such a specification might
(define option-spec '((version (single-char #\v) (value #f)) (help (single-char #\h) (value #f))))
This alist tells
getopt-long that it should accept two long
options, called version and help, and that these options
can also be selected by the single-letter abbreviations v and
h, respectively. The
(value #f) clauses indicate that
neither of the options accepts a value.
With this specification we can use
getopt-long to parse a given
(define options (getopt-long (command-line) option-spec))
After this call,
options contains the parsed command line and is
ready to be examined by
option-ref is called
(option-ref options 'help #f)
It expects the parsed command line, a symbol indicating the option to
examine, and a default value. The default value is returned if the
option was not present in the command line, or if the option was present
but without a value; otherwise the value from the command line is
option-ref is called once for each possible
option that a script supports.
The following example shows a main program which puts all this together to parse its command line and figure out what the user wanted.
(define (main args) (let* ((option-spec '((version (single-char #\v) (value #f)) (help (single-char #\h) (value #f)))) (options (getopt-long args option-spec)) (help-wanted (option-ref options 'help #f)) (version-wanted (option-ref options 'version #f))) (if (or version-wanted help-wanted) (begin (if version-wanted (display "getopt-long-example version 0.3\n")) (if help-wanted (display "\ getopt-long-example [options] -v, --version Display version -h, --help Display this help "))) (begin (display "Hello, World!") (newline)))))
An option specification is an association list (see section Association Lists) with one list element for each supported option. The key of each list element is a symbol that names the option, while the value is a list of option properties:
OPTION-SPEC ::= '( (OPT-NAME1 (PROP-NAME PROP-VALUE) ...) (OPT-NAME2 (PROP-NAME PROP-VALUE) ...) (OPT-NAME3 (PROP-NAME PROP-VALUE) ...) ... )
Each opt-name specifies the long option name for that option. For
example, a list element with opt-name
an option that can be specified on the command line using the long
--background. Further information about the option ---
whether it takes a value, whether it is required to be present in the
command line, and so on -- is specified by the option properties.
In the example of the preceding subsection, we already saw that a long
option name can have a equivalent short option character. The
equivalent short option character can be set for an option by specifying
single-char property in that option's property list. For
example, a list element like
'(output (single-char #\o) ...)
specifies an option with long name
--output that can also be
specified by the equivalent short name
value property specifies whether an option requires or
accepts a value. If the
value property is set to
option requires a value:
getopt-long will signal an error if the
option name is present without a corresponding value. If set to
#f, the option does not take a value; in this case, a non-option
word that follows the option name in the command line will be treated as
a non-option argument. If set to the symbol
optional, the option
accepts a value but does not require one: a non-option word that follows
the option name in the command line will be interpreted as that option's
value. If the option name for an option with
is immediately followed in the command line by another option
name, the value for the first option is implicitly
required? property indicates whether an option is required to
be present in the command line. If the
required? property is
getopt-long will signal an error if the option
is not specified.
predicate property can be used to constrain the
possible values of an option. If used, the
should be set to a procedure that takes one argument -- the proposed
option value as a string -- and returns either
according as the proposed value is or is not acceptable. If the
predicate procedure returns
getopt-long will signal an
By default, options do not have single-character equivalents, are not
required, and do not take values. Where the list element for an option
value property but no
predicate property, the
option values are unconstrained.
In order for
getopt-long to correctly parse a command line, that
command line must conform to a standard set of rules for how command
line options are specified. This subsection explains what those rules
getopt-long splits a given command line into several pieces. All
elements of the argument list are classified to be either options or
normal arguments. Options consist of two dashes and an option name
(so-called long options), or of one dash followed by a single
letter (short options).
Options can behave as switches, when they are given without a value, or they can be used to pass a value to the program. The value for an option may be specified using an equals sign, or else is simply the next word in the command line, so the following two invocations are equivalent:
$ ./foo.scm --output=bar.txt $ ./foo.scm --output bar.txt
Short options can be used instead of their long equivalents and can be grouped together after a single dash. For example, the following commands are equivalent.
$ ./foo.scm --version --help $ ./foo.scm -v --help $ ./foo.scm -vh
If an option requires a value, it can only be grouped together with other short options if it is the last option in the group; the value is the next argument. So, for example, with the following option specification ---
((apples (single-char #\a)) (blimps (single-char #\b) (value #t)) (catalexis (single-char #\c) (value #t)))
--- the following command lines would all be acceptable:
$ ./foo.scm -a -b bang -c couth $ ./foo.scm -ab bang -c couth $ ./foo.scm -ac couth -b bang
But the next command line is an error, because
-b is not the last
option in its combination, and because a group of short options cannot
include two options that both require values:
$ ./foo.scm -abc couth bang
If an option's value is optional,
getopt-long decides whether the
option has a value by looking at what follows it in the argument list.
If the next element is a string, and it does not appear to be an option
itself, then that string is the option's value.
If the option
-- appears in the argument list, argument parsing
stops there and subsequent arguments are returned as ordinary arguments,
even if they resemble options. So, with the command line
$ ./foo.scm --apples "Granny Smith" -- --blimp Goodyear
getopt-long will recognize the
--apples option as having
the value "Granny Smith", but will not treat
--blimp as an
option. The strings
Goodyear will be returned
as ordinary argument strings.
The grammar argument is expected to be a list of this form:
((option (property value) ...) ...)
where each option is a symbol denoting the long option, but
without the two leading dashes (e.g.
version if the option is
For each option, there may be list of arbitrarily many property/value pairs. The order of the pairs is not important, but every property may only appear once in the property list. The following table lists the possible properties:
-charas a single-character equivalent to
--option. This is how to specify traditional Unix-style flags.
getopt-longwill raise an error if it is not found in args.
#t, the option accepts a value; if it is
#f, it does not; and if it is the symbol
optional, the option may appear in args with or without a value.
(value #t)for this option), then
getopt-longwill apply func to the value, and throw an exception if it returns
#f. func should be a procedure which accepts a string and returns a boolean value; you may need to use quasiquotes to get it into grammar.
getopt-long's args parameter is expected to be a list of
strings like the one returned by
command-line, with the first
element being the name of the command. Therefore
ignores the first element in args and starts argument
interpretation with the second element.
getopt-long signals an error if any of the following conditions
#t. If the option was not given, return default. options must be the result of a call to
option-ref always succeeds, either by returning the requested
option value from the command line, or the default value.
The special key
'() can be used to get a list of all
Go to the first, previous, next, last section, table of contents.