README.md

# ExCmd [![Hex.pm](https://img.shields.io/hexpm/v/ex_cmd.svg)](https://hex.pm/packages/ex_cmd)

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

ExCmd is built around the idea of streaming data through an external program. Think streaming a video through `ffmpeg` to serve a web request. For example, getting audio out of a stream is as simple as
``` elixir
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()
```

## Overview
ExCmd uses [odu](https://github.com/akash-akya/odu) middleware to interact with external process. It uses a demand-driven protocol for IO to have back-pressure. `ExCmd.stream!` is a stream interface for interacting with the command. One should prefer to use this over `ExCmd.Process`. Use `ExCmd.Process` if you need more control.

Check [documentation](https://hexdocs.pm/ex_cmd/readme.html) for information

### Major advantages over port
* Unlike beam ports, ExCmd puts back pressure on the external program
* Proper program termination. No more zombie process
* Ability to close stdin and wait for output (with ports one can not selectively close stdin)
* Stream abstraction

**Check out [Exile](https://github.com/akash-akya/exile) which is an alternative solution based on NIF**

**Note: ExCmd is still WIP. Expect breaking changes**

## Installation
1. Install [odu](https://github.com/akash-akya/odu/releases/tag/v0.2.3) v0.2.3 and make sure its in your path
2. Install ExCmd
```elixir
def deps do
  [
    {:ex_cmd, "~> x.x.x"}
  ]
end
```