In this tutorial we learn how to read command line arguments directly, using
Sys.argv array, and then how to do so more easily using the standard
Like in C and many other languages, the arguments that are passed to a given
program on the command line are stored in an array. Following tradition, this
array is named
argv. It is found in the
Sys module of the standard library,
therefore its full name is
Sys.argv. The number of arguments including the
name of the program itself is simply the length of the array. It is obtained
The following program displays the arguments with their position in
let () = for i = 0 to Array.length Sys.argv - 1 do Printf.printf "[%i] %s\n" i Sys.argv.(i) done
If you save the program above as
args.ml, and run
ocaml args.ml arg1 arg2 arg3, here is what you get:
$ ocaml args.ml arg1 arg2 arg3  args.ml  arg1  arg2  arg3
ocaml launched a subprocess that actually runs the program where
args.ml arg1 arg2 arg3. You can also compile your program using
ocamlopt -o args args.ml, and then running
./args arg1 arg2 arg3 and you
$ ocamlopt -o args args.ml $ ./args arg1 arg2 arg3  ./args  arg1  arg2  arg3
The OCaml standard library has a module for writing command line interfaces, so
we do not have to use
Sys.argv directly. We shall consider the example from
the OCaml documentation, a program for appending files.
First, we set up the usage message to be printed in the case of a malformed command line, or when help is requested:
let usage_msg = "append [-verbose] <file1> [<file2>] ... -o <output>"
Now, we create some references to hold the information gathered from the
command line. The
Arg module will fill these in for us as the command line is
let verbose = ref false let input_files = ref  let output_file = ref ""
We have a boolean reference for the
-verbose flag with a default value of
false. Then we have a reference to a list which will hold the names of all
the input files. Finally, we have a string reference into which the single
output file name specified by
-o will be placed.
We will need a function to handle the anonymous inputs, that is to say the ones with no flag before them. In this case these are our input file names. Our function simply adds the file name to the reference defined earlier.
let anon_fun filename = input_files := filename :: !input_files
Finally we build the list of command line flag specifcations. Each is a tuple of the flag name, the action to be taken when it is encountered, and the help string.
let speclist = [ ("-verbose", Arg.Set verbose, "Output debug information"); ("-o", Arg.Set_string output_file, "Set output file name"); ]
We have two kinds of action here: the
Arg.Set action which sets a boolean
reference, and the
Arg.Set_string action which sets a string reference. Our
input_files reference will of course be updated by the
We can now call
Arg.parse, giving it our specification list, anonymous
function, and usage message. Once it returns, the references will be filled
with all the information required to append our files.
let () = Arg.parse speclist anon_fun usage_msg (* Main functionality here *)
Let's save our program as
append.ml and compile it with
ocamlopt -o append append.ml and try it out:
$ ocamlopt -o append append.ml $ ./append -verbose one.txt two.txt -o three.txt $ ./append one.txt two.txt $ ./append -quiet ./append: unknown option '-quiet'. append [-verbose] <file1> [<file2>] ... -o <output> -verbose Output debug information -o Set output file name -help Display this list of options --help Display this list of options  $ ./append -help append [-verbose] <file1> [<file2>] ... -o <output> -verbose Output debug information -o Set output file name -help Display this list of options --help Display this list of options
Here is the whole program:
let usage_msg = "append [-verbose] <file1> [<file2>] ... -o <output>" let verbose = ref false let input_files = ref  let output_file = ref "" let anon_fun filename = input_files := filename :: !input_files let speclist = [("-verbose", Arg.Set verbose, "Output debug information"); ("-o", Arg.Set_string output_file, "Set output file name")] let () = Arg.parse speclist anon_fun usage_msg; (* Main functionality here *)
Arg module has many more actions than just
some lower-level function for parsing more complicated command lines.
Other Tools for Parsing Command-Line Options
There are libraries with facilities different from or more extensive than the
Cmdliner is a modern interface for command line processing, which also generates UNIX man pages automatically.
Clap is an imperative command line parser.
Minicli has good support for rejecting malformed command lines which others might sliently accept.
Getopt for OCaml is similar to GNU getopt.
Help Improve Our Documentation
All OCaml docs are open source. See something that's wrong or unclear? Submit a pull request.Contribute