Sometimes we need to execute system commands from within a Ruby app or script. You can find some methods in the Kernel module to accomplish this, but they behave slightly different. Let's take a look at all those methods and see what are their main differences.
exec("command")
This is the least common and least useful method for running external commands. exec
replaces the current process (your Ruby script) by running the external command.
> exec('ls')
We rarely want this behaviour so let's see different ways to run system commands.
command
or %x{ command }
Backticks are the easiest and quickest way to run a command. Simply enclose the command you want to run in backticks like this:
> `ls`
=> "bin\ncode\n"
If you prefer, you can get the same exact result using %x
> %x{ ls }
=> "bin\ncode\n"
Both return the standard output of running the command in a subshell.
system("command")
If you want to explicitly check if the command was found and ran successfully, you can use the system
command. Unlike the backtick or %x
method, system
will execute the command and return true
if the command was successful (exit status 0), false if it was unsuccessful (exit status 1) or nil if the command execution failed.
> system('ls')
bin code
=> true
> system('ls x')
ls: x: No such file or directory
=> false
> system('foo')
=> nil
Special variables
For all of those methods mentioned above, you can access the PID and exit status of the unix process via the $?
variable:
> system('ls')
bin code
=> true
> $?.pid
=> 123
> $?.exitstatus
=> 0
IO#popen
This method executes the specified command as a subprocess, as a result it will return an IO object containing both input and output, allowing you to use some convenient methods to access the output and the PID.
> command = IO.popen("ls -l")
> command.pid
=> 123
> command.readlines
=> ["total 8\n",
"-rwxr-xr-x 1 emili staff 40 Feb 11 20:25 hello.rb\n",
"drwxr-xr-x 4 emili staff 136 Jan 30 13:16 foo.rb\n"]
Top comments (0)