Skip to content
forked from akash-akya/ex_cmd

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

License

Notifications You must be signed in to change notification settings

bfolkens/ex_cmd

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ExCmd

CI Hex.pm docs

ExCmd is an Elixir library to run and communicate with external programs with back-pressure mechanism. It makes use os provided stdio buffer for this.

Communication with external program using Port is not demand driven. So it is easy to run into memory issues when the size of the data we are writing or reading from the external program is large. ExCmd tries to solve this problem by making better use of os provided stdio buffers and providing demand-driven interface to write and read from external program. It can be used to stream data through an external program. For example, streaming a video through ffmpeg to serve a web request.

Getting audio out of a video stream is as simple as

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()

Major Features

  • Unlike beam ports, ExCmd puts back pressure on the external program
  • Stream abstraction
  • No separate shim installation required
  • Ships pre-built binaries for MacOS, Windows, Linux
  • Proper program termination. No more zombie process
  • Ability to close stdin and wait for output (with ports one can not selectively close stdin)

If you are not interested in streaming capability, ExCmd can still be useful because of the features listed above. For example running command and getting output as a string

ExCmd.stream!(~w(curl ifconfig.co))
|> Enum.into("")

If you want to use shell to handle more complex pipelines and globs, you can just spawn shell process and pass your shell command as the argument

cmd = "echo 'foo baar' | base64"
ExCmd.stream!(["sh", "-c", cmd])
|> Enum.into("")

Refer documentation for information

Check out Exile which is an alternative solution based on NIF without middleware overhead

Installation

def deps do
  [
    {:ex_cmd, "~> x.x.x"}
  ]
end

About

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

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 75.8%
  • Go 24.2%