View Source ExCmd (ex_cmd v0.12.0)

ExCmd is an Elixir library to run and communicate with external programs with back-pressure.

Summary

Functions

Runs the given command with arguments and return an Enumerable to read command output.

Types

@type collectable_func() :: (Collectable.t() -> any())

Functions

Link to this function

stream!(cmd_with_args, opts \\ [])

View Source
@spec stream!([String.t(), ...],
  input: Enum.t() | collectable_func(),
  exit_timeout: timeout(),
  cd: String.t(),
  env: [{String.t(), String.t()}],
  log: boolean()
) :: ExCmd.Stream.t()

Runs the given command with arguments and return an Enumerable to read command output.

First parameter must be a list containing command with arguments. example: ["cat", "file.txt"].

Optional

  • input - Input can be binary, iodata, Enumerable (list, stream) or a function which accepts Collectable.

    • Binary

      # binary
      ExCmd.stream!(~w(base64), input: "Hello Wolrd")
    • Enumerable or iodata

      # list
      ExCmd.stream!(~w(base64), input: ["hello", "world"])
      
      # iodata
      ExCmd.stream!(~w(cat), input: ["He", ["llo"], [' ', ?W], ['or', "ld"]])
      
      # stream
      ExCmd.stream!(~w(cat), input: File.stream!("log.txt", [], 65536))
    • Collectable:

      If the input in a function with arity 1, ExCmd will call that function with a Collectable as the argument. The function must push input to this collectable. Return value of the function is ignored.

      ExCmd.stream!(~w(cat), input: fn sink ->
        Enum.into(1..100, sink, &to_string/1)
      end)
  • exit_timeout - Time to wait for external program to exit. After writing all of the input we close the stdin stream and wait for external program to finish and exit. If program does not exit within exit_timeout an error will be raised and subsequently program will be killed in background. Defaults timeout is :infinity.

All other options are passed to ExCmd.Process.start_link/2

Examples

ExCmd.stream!(~w(ffmpeg -i pipe:0 -f mp3 pipe:1), input: File.stream!("music_video.mkv", [], 65336))
|> Stream.into(File.stream!("music.mp3"))
|> Stream.run()

With input as binary

iex> ExCmd.stream!(~w(cat), input: "Hello World")
...> |> Enum.into("")
"Hello World"
iex> ExCmd.stream!(~w(base64), input: <<1, 2, 3, 4, 5>>)
...> |> Enum.into("")
"AQIDBAU=
"

With input as list

iex> ExCmd.stream!(~w(cat), input: ["Hello ", "World"])
...> |> Enum.into("")
"Hello World"

With input as iodata

iex> ExCmd.stream!(~w(base64), input: [<<1, 2,>>, [3], [<<4, 5>>]])
...> |> Enum.into("")
"AQIDBAU=
"

When program exit abnormally it will raise ExCmd.Stream.AbnormalExit error with exit_status.

iex> try do
...>   ExCmd.stream!(["sh", "-c", "exit 5"]) |> Enum.to_list()
...> rescue
...>   e in ExCmd.Stream.AbnormalExit ->
...>    e.exit_status
...> end
5