Does anyone know a standard package for tcl to easily parse the input arguments ? or a ready proc ? ( I have only 3 flags but something general is preferable ).
Asked
Active
Viewed 7,396 times
2
-
Wanting that behaviour for 3 flags is like to kill a fly using a bomb! – sergiol Feb 20 '17 at 01:24
3 Answers
9
The documentation includes an example. Here is a simple example:
package require cmdline
set parameters {
{server.arg "" "Which server to search"}
{debug "Turn on debugging, default=off"}
}
set usage "- A simple script to demo cmdline parsing"
array set options [cmdline::getoptions ::argv $parameters $usage]
parray options
Sample runs:
$ tclsh simple.tcl
options(debug) = 0
options(server) =
$ tclsh simple.tcl -server google.com
options(debug) = 0
options(server) = google.com
$ tclsh simple.tcl -server google.com -debug
options(debug) = 1
options(server) = google.com
$ tclsh simple.tcl -help
simple - A simple script to demo cmdline parsing
-server value Which server to search <>
-debug Turn on debugging, default=off
-help Print this message
-? Print this message
while executing
"error [usage $optlist $usage]"
(procedure "cmdline::getoptions" line 15)
invoked from within
"cmdline::getoptions ::argv $parameters $usage"
invoked from within
"array set options [cmdline::getoptions ::argv $parameters $usage]"
(file "simple.tcl" line 11)
Discussion
- Unlike most Linux utilities, TCL uses single dash instead of double dashes for command-line options
- When a flags ends with .arg, then that flag expects an argument to follow, such as in the case of server.arg
- The debug flag does not end with .arg, therefore it does not expect any argument
- The user defines the command-line parameters by a list of lists. Each sub-list contains 2 or 3 parts:
- The flag (e.g. debug)
- The default value (e.g. 0), only if the parameter takes an argument (flag ends with
.arg
). - And the help message
- Invoke usage/help with
-help
or-?
, however, the output is not pretty, see the last sample run.
Update: Help/Usage
I have been thinking about the message output when the user invoke help (see the last sample run above). To get around that, you need to trap the error yourself:
set usage "- A simple script to demo cmdline parsing"
if {[catch {array set options [cmdline::getoptions ::argv $parameters $usage]}]} {
puts [cmdline::usage $parameters $usage]
} else {
parray options
}
Sample run 2:
$ tclsh simple.tcl -?
simple - A simple script to demo cmdline parsing
-server value Which server to search <>
-debug Turn on debugging, default=off
-help Print this message
-? Print this message
-
Thanks a lot, is there any way to declare required arguments and optional arguments ? – Foad Rezek Jun 22 '14 at 06:32
-
There is no provision for specifying required arguments--everything is optional. You will have to test each option against the default value to determine if an option was missing from the command line. – Hai Vu Jun 22 '14 at 08:07
-
Ok, last question - any supported method for showing help menu / usage ? – Foad Rezek Jun 22 '14 at 08:13
-
I updated to remove the default value given to `-debug` to fix the help output... Now, I'm wondering if there is a way to set the default value of a boolean argument to `1`. It seems this library does accept using a `+debug` syntax to set such options to `0`. – JoL May 31 '17 at 18:28
-
I just tried adding `1` as the default value for `debug`, but the default value was still `0` and cmdline used the `1` as the help description. I'm guessing a default simply can't be set for such parameters and will always be `0`. – JoL May 31 '17 at 18:35
2
Tcllib has such a package, cmdline. It's a bit underdocumented, but it works.

Peter Lewerin
- 13,140
- 1
- 24
- 27
0
Here is a simple, native, no-package argument parser:
#
# arg_parse simple argument parser
# Example `arg_parse {help version} {with-value} {-with-value 123 positional arguments}`
# will return:
# `positionals {positional arguments} with-value 123`
#
# @param boolean_flags flags which does not requires additional arguments (like help)
# @param argument_flags flags which requires values (-with-value value)
# @param args the got command line arguments
#
# @return stringified array of parsed arguments
#
proc arg_parse { boolean_flags argument_flags args } {
set argsarr(positionals) {}
for {set i 0} {$i < [llength $args]} {incr i} {
set arg [lindex $args $i]
if { [sstartswith $arg "-" ] } {
set flag [string range $arg 1 end]
if { [lsearch $boolean_flags $flag] >= 0 } {
set argsarr($flag) 1
} elseif { [lsearch $argument_flags $flag] >= 0 } {
incr i
set argsarr($flag) [lindex $args $i]
} else {
puts "ERROR: Unknown flag argument: $arg"
return
}
} else {
lappend argsarr(positionals) $arg
}
}
return [array get argsarr]
}
USE argument parser
#
# USE argument parser:
#
proc my_awesome_proc { args } {
array set argsarr [arg_parse "help version" "with-value" {*}$args]
parray argsarr
}
USE my_awesome_proc :
% my_awesome_proc -help
argsarr(help) = 1
argsarr(positionals) =
% my_awesome_proc -with-value 123
argsarr(positionals) =
argsarr(with-value) = 123
% my_awesome_proc -wrong
ERROR: Unknown flag argument: -wrong
% my_awesome_proc positional arguments
argsarr(positionals) = positional arguments
%

betontalpfa
- 3,454
- 1
- 33
- 65