Execing Processes in Crystal

Our example demonstrates how to replace the current process with another one using Crystal’s implementation of the classic exec function.

require "process"

# For our example we'll exec `ls`. Crystal requires the
# full path to the binary we want to execute, so we'll use
# `Process.find_executable` to find it (probably `/bin/ls`).
binary = Process.find_executable("ls")
if binary.nil?
  raise "Could not find 'ls' executable"
end

# `exec` requires arguments in array form (as opposed to
# one big string). We'll give `ls` a few common arguments.
# Note that the first argument should be the program name.
args = ["ls", "-a", "-l", "-h"]

# `exec` also needs a set of environment variables to use.
# Here we just provide our current environment.
env = ENV.to_h

# Here's the actual `Process.exec` call. If this call is
# successful, the execution of our process will end here
# and be replaced by the `/bin/ls -a -l -h` process.
# If there is an error, an exception will be raised.
Process.exec(binary, args, env)

When we run our program it is replaced by ls.

$ crystal exec_processes.cr
total 16K
drwxr-xr-x  4 user user 4.0K Oct 3 16:29 .
drwxr-xr-x 91 user user 4.0K Oct 3 12:50 ..
-rw-r--r--  1 user user 1.3K Oct 3 16:28 exec_processes.cr

Note that Crystal, like many high-level languages, does not offer a classic Unix fork function. However, Crystal provides other mechanisms for concurrency and process management, such as fibers and spawning processes, which cover most use cases where you might use fork in other languages.