IO, Files, Paths & System

24.1 IO

IO.puts("line")                    # with newline
IO.write("no newline")
IO.inspect(%{a: 1}, label: "map", pretty: true, limit: :infinity)
name = IO.gets("Name? ") |> String.trim()
IO.puts(:stderr, "error!")
IO.ANSI.red() <> "red text" <> IO.ANSI.reset()
IO.read(:stdio, :eof)              # read all stdin (1.13+ uses :eof)
IO.stream(:stdio, :line) |> Enum.each(&IO.write/1)

24.2 File

File.read("a.txt")                  # {:ok, content} | {:error, reason}
File.read!("a.txt")
File.write!("out.txt", "hello\n")
File.write!("log.txt", "more\n", [:append])
File.exists?("a.txt"), File.dir?("lib"), File.regular?("a.txt")
File.ls!("."), File.mkdir_p!("a/b/c"), File.rm!("x"), File.rm_rf!("dir")
File.cp!("a", "b"), File.rename!("a", "b"), File.stat!("a.txt").size
File.stream!("big.csv") |> Stream.map(&String.trim/1) |> Enum.take(5)
File.open!("f.txt", [:write, :utf8], fn file -> IO.write(file, "hi") end)

24.3 Path

Path.join(["lib", "app", "user.ex"])
Path.expand("~/code"), Path.absname("x")
Path.basename("/a/b.ex"), Path.dirname("/a/b.ex"), Path.extname("b.ex")
Path.rootname("b.ex"), Path.split("/a/b"), Path.wildcard("lib/**/*.ex")
Path.relative_to("/a/b/c", "/a")

24.4 System

System.get_env("HOME"), System.fetch_env!("DATABASE_URL"), System.put_env("X", "1")
System.argv()
{output, 0} = System.cmd("git", ["status"], stderr_to_stdout: true)
System.shell("echo hi | tr a-z A-Z")   # 1.12+
System.monotonic_time(:millisecond), System.system_time(:second), System.os_time()
System.schedulers_online(), System.version(), System.otp_release()
System.halt(0), System.stop()
System.at_exit(fn status -> IO.puts("bye #{status}") end)

24.5 Scripting with Mix.install

#!/usr/bin/env elixir
Mix.install([{:req, "~> 0.5"}, {:jason, "~> 1.4"}])

Req.get!("https://api.github.com/repos/elixir-lang/elixir").body["stargazers_count"]
|> IO.puts()

24.6 Escripts

# mix.exs
def project, do: [app: :cli, version: "0.1.0", escript: [main_module: CLI]]
defmodule CLI do
  def main(args) do
    {opts, rest, _} = OptionParser.parse(args, strict: [verbose: :boolean, name: :string], aliases: [v: :verbose])
    IO.inspect({opts, rest})
  end
end
mix escript.build && ./cli --name Ann -v file.txt