Suppose I want to check if some executable, foo, is valid prior to calling it with its arguments. Various means of doing so are available from the command line (e.g., $> hash foo).
However, to my knowledge, neither OCaml's Sys nor Unix modules provide such functionality build-in.
How might one define idiomatically a mechanism that accepts a string indicating a unix executable and returns a bool indicating if the argument is executable?
The function that allows you to check whether a file is executable or not is Unix.access. If you want to additionally search the path, you'll need additional scaffolding, e.g.:
let syspath = String.split_on_char ':' (Sys.getenv "PATH")
let check_executable path =
let open Unix in
try
access path [ X_OK ]; Some path
with _ -> None
let starts_with s prefix =
let open String in
let plen = length prefix in
length s >= plen && sub s 0 plen = prefix
let search_path name =
if starts_with name "/" || starts_with name "./" || starts_with name "../"
then
check_executable name
else
List.fold_left (fun acc dir ->
match acc with
| Some file -> Some file
| None ->
check_executable (Filename.concat dir name)
) None syspath
let main () =
Array.iter (fun arg ->
match search_path arg with
| None -> Printf.printf "%s (Not found)\n" arg
| Some file -> Printf.printf "%s -> %s\n" arg file)
Array.(sub Sys.argv 1 (length Sys.argv - 1))
let () = main ()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With