Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if executable is valid

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?

like image 226
David Shaked Avatar asked Jun 23 '26 14:06

David Shaked


1 Answers

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 ()
like image 197
Reimer Behrends Avatar answered Jun 26 '26 11:06

Reimer Behrends