module Wrapper:Handling shell scripts in OCaml. A general technique for wrapping shell commands or scripts is proposed in this module. The technique is applied in the modulesig..end
Shell for building a significative set
of ready-to-use wrappers corresponding to the most famous Unix tools
(grep, dd, tar,..).typecommand =string
typecontent =string
typearg =string
typecall =string
"ls" or "wc -l" or "cat | grep -v".typescript =string
$1, $2,...
as for instance "test -d $1 && echo true".
A script is not directly executable but can be easily enveloped in a shell function
in order to become executable by the shell interpreter.val envelop : ?name:string -> script -> callExample:
# print_endline (envelop "test -d $1");;
function auxfun418234 () {
test -d $1
}
auxfun418234
: unit = ()
?args:'a
|
+-----+-----+
| ?at | argument(s)
?opt +-----+-----+ treatment
| |
+----------+--+
+-----------+ | Unix.shell | +-----------+
?input:'b -->+ ?it +-------->+ +-------->+ ~ot +-->'c
+-----------+ | command | +-----------+
input treatment +-------------+ output treatment
val make : ?at:('a -> string) option ->
?it:('b -> UnixExtra.Unix.content) option ->
ot:(string -> 'c) ->
?script:bool ->
command ->
?opt:string -> ?args:'a option -> ?input:'b option -> unit -> 'c
~it (the input treatment, by default None) represent the action
to execute before the command, in order to transform a value of a
type 'b into a string; the result
will be used as standard input for the command;~ot (the output treatment) represent the action
to execute after the command
in order to transform its standard output (a string)
in a value of an arbitrary type 'c;~at (the argument treatment, by default None) permits a similar
re-arrangement of the signature,
but for the argument(s) of the command, which could be of any type 'a (then
also a tuple). This function converts the argument(s) in a string,
which is the suitable type for the command; ~opt="") are appended as-is at right side of the
command and before the string representation of arguments. ~script is set the command is enveloped in order to allow the
use of positionnal parameters $1, $2,... By default ~script=false.
The function raises a failure if an argument or an input is provided
(in the form Some v)
while the corresponding treatment is undefined (equals to None).
val textfilter : ?at:('a -> string) option ->
?script:bool ->
command ->
?opt:string -> ?args:'a option -> StringExtra.String.line list -> string listWrapper.make
for building wrappers dealing with texts (string lists):~it is set to Some String.Text.to_string~ot is set to String.Text.of_stringmodule Treat:sig..end
Basically, the wrapper constructor may be used in a "quick and easy" way using strings
as parameters of the resulting wrapper. Instead, the more sofisticated way constists
in defining a real abstract syntax for parameters and/or inputs, in order to avoid
bad calls of the wrapper at compile-time.
Quick and easy wrapper
(* A wrapper for the command date *)
let date ?(opt="") ?(arg="") () =
make ~at:Treat.identity ~ot:String.chop "date" ~args:(Some arg) ~opt () ;;
(* Examples of usage: *)
# date () ;;
: string = "lun avr 16 14:28:57 CEST 2007"
# date ~opt:"-r" ~arg:"shell.ml" () ;;
: string = "sam avr 14 16:58:22 CEST 2007"
# date ~arg:"-r shell.ml" () ;;
: string = "sam avr 14 16:58:22 CEST 2007"
(* A wrapper for the command date with an abstract syntax for parameters. *)
module Date = struct
(* (1) Define your abstract syntax (for parameters and/or input and/or output).
In this case for parameters: *)
type options = Option_f of string | Option_r of string | Option_R ;;
type synopsis = options list ;;
(* (2) Define your conversion(s) *)
let string_of_options = function
| Option_f x -> "-f "^x
| Option_r x -> "-r "^x
| Option_R -> "-R "
;;
let string_of_synopsis = String.merge_map string_of_options;;
(* (3) Apply the wrapper constructor *)
let date (args:synopsis) =
make ~at:(Some string_of_synopsis) ~ot:String.chop "date" ~args:(Some args) ()
;;
end;;
(* Example of usage *)
# date [Option_r "shell.ml"];;
: string = "sam avr 14 16:58:22 CEST 2007"