let execute s =
      wrap_deferred ~on_exn:(fun e -> `Shell (s, `Exn e))
        Lwt.(fun () ->
          let inprocess = Lwt_process.(open_process_full (shell s)) in
          Lwt_list.map_p Lwt_io.read
            [inprocess#stdout; inprocess#stderr; ]
          >>= fun output ->
          inprocess#status >>= fun status ->
          return (status, output))
      >>= fun (ret, output) ->
      let code =
        match ret with
        | Lwt_unix.WEXITED n ->   (`Exited n)
        | Lwt_unix.WSIGNALED n -> (`Signaled n)
        | Lwt_unix.WSTOPPED n ->  (`Stopped n)
      in
      begin match output with
      | [out; err] -> return (out, err, code)
      | _ -> assert false
      end