Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/elixir/lib/port.ex
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ defmodule Port do

Spawn executable is a more restricted and explicit version of spawn. It expects
full file paths to the executable you want to execute. If they are in your `$PATH`,
they can be retrieved by calling `System.find_executable/1`:
they can be retrieved by calling `System.find_executable!/1`:

iex> path = System.find_executable("echo")
iex> path = System.find_executable!("echo")
iex> port = Port.open({:spawn_executable, path}, [:binary, args: ["hello world"]])
iex> flush()
{#Port<0.1380>, {:data, "hello world\n"}}
Expand Down
34 changes: 33 additions & 1 deletion lib/elixir/lib/system.ex
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,19 @@ defmodule System do
operating systems. It also considers the proper executable
extension for each operating system, so for Windows it will try to
lookup files with `.com`, `.cmd` or similar extensions.

See also `find_executable!/1`.

## Examples

System.find_executable("bash")
#=> "/bin/bash"

System.find_executable("unknown")
#=> nil

"""
@spec find_executable(binary) :: binary | nil
@spec find_executable(binary()) :: binary() | nil
def find_executable(program) when is_binary(program) do
assert_no_null_byte!(program, "System.find_executable/1")

Expand All @@ -641,6 +652,27 @@ defmodule System do
end
end

@doc """
Locates an executable on the system or raises an error.

See also `find_executable/1`.

## Examples

System.find_executable!("bash")
#=> "/bin/bash"

System.find_executable!("unknown")
** (RuntimeError) could not find executable "unknown" in PATH

"""
@doc since: "1.20.0"
@spec find_executable!(binary()) :: binary()
def find_executable!(program) when is_binary(program) do
find_executable(program) ||
raise "could not find executable #{inspect(program)} in PATH"
end

@doc """
Returns all system environment variables.

Expand Down
4 changes: 2 additions & 2 deletions lib/elixir/test/elixir/system_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ defmodule SystemTest do
test "cmd/3 with absolute and relative paths", config do
echo = Path.join(config.tmp_dir, @echo)
File.mkdir_p!(Path.dirname(echo))
File.ln_s!(System.find_executable("cmd"), echo)
File.ln_s!(System.find_executable!("cmd"), echo)

File.cd!(Path.dirname(echo), fn ->
# There is a bug in OTP where find_executable is finding
Expand Down Expand Up @@ -210,7 +210,7 @@ defmodule SystemTest do
test "cmd/3 with absolute and relative paths", config do
echo = Path.join(config.tmp_dir, @echo)
File.mkdir_p!(Path.dirname(echo))
File.ln_s!(System.find_executable("echo"), echo)
File.ln_s!(System.find_executable!("echo"), echo)

File.cd!(Path.dirname(echo), fn ->
# There is a bug in OTP where find_executable is finding
Expand Down