How to use System.cmd’s :into option with /dev/null?

Hello…

How to use System.cmd’s :into option with /dev/null?

Something like…

System.cmd("foo", [], into: IO.stream("/dev/null", :line))

Thanks for the help!

If you want to avoid having Elixir reading the output altogether, then you’re going to have to have the OS do the redirection for you. You can do that running the command in a shell, e.g. System.cmd("sh", ["-c", "foo >/dev/null"]). But this is only really safe if the command and its arguments are fully under your control. If there is any user input involved, this approach can make your application vulnerable to command injection! More about that here.

If instead you just want Elixir to consume the output chunks and not collect them in memory, writing to an IO stream is not going to be very efficient. Instead you could implement a null collectable like this:

defmodule DevNull do
  defstruct []

  defimpl Collectable do
    def into(original) do        
      collector_fun = fn         
        _dev_null, :halt -> :ok  
        dev_null, _ -> dev_null  
      end
      {original, collector_fun}
    end
  end
end

System.cmd("foo", [], into: %DevNull{})

But that’s only really needed for commands that produce a lot of output. In most cases I would skip :into altogether and just ignore the first element of the return value of System.cmd/2.

4 Likes