Execute a Shell Process in F#

Update 2022-01: Check out library Fli.

Synchronously execute a process and wait for it to return; capturing the exit code, stdout, and stderr. It’s a snippet that I often reach for but I can never find it on the internet. Dotnet makes it more difficult than it really should be.

let result = executeProcess "uptime" "-p"

printfn "Exit code: %d" result.ExitCode
printfn "StdOut: %s" result.StdOut

(*
  Exit code: 0
  StdOut: up 2 days, 20 hours, 55 minutes
*)

F# reserves the symbol process so names are slightly awkward.

open System

type ProcessResult = { 
    ExitCode : int; 
    StdOut : string; 
    StdErr : string 
}

let executeProcess (processName: string) (processArgs: string) =
    let psi = new Diagnostics.ProcessStartInfo(processName, processArgs) 
    psi.UseShellExecute <- false
    psi.RedirectStandardOutput <- true
    psi.RedirectStandardError <- true
    psi.CreateNoWindow <- true        
    let proc = Diagnostics.Process.Start(psi) 
    let output = new Text.StringBuilder()
    let error = new Text.StringBuilder()
    proc.OutputDataReceived.Add(fun args -> output.Append(args.Data) |> ignore)
    proc.ErrorDataReceived.Add(fun args -> error.Append(args.Data) |> ignore)
    proc.BeginErrorReadLine()
    proc.BeginOutputReadLine()
    proc.WaitForExit()
    { ExitCode = proc.ExitCode; StdOut = output.ToString(); StdErr = error.ToString() }

Originally based on this implementation.


Related Posts