Ruby running Terminal Commands

There’s already several other articles talking about what you can do to run terminal commands from Ruby code. They all provide great reference material but are focused more on what the methods are than why you would want to use them. That’s not necessarily how I think so I wanted to share my perspective on the different methods available.

If you just want to make a call and return the output, backticks (`) are a great choice. You provide the input, it runs it, and it returns the text output:

html = `curl`

If you need asynchronous calls, spawn is probably the way to go. You can run Ruby blocks in a similar way with fork. Both methods create a subprocess and return the PID:

pid = spawn 'sleep 10'
Process.wait pid

If you actually want to shell out the command, exec and system are solid choices. They differ in certain ways but both allow you to provide environment variables and output text just as if you had run the command:

system 'echo foo'
=> foo
system {'TEST'=>'bar'}, 'echo $TEST'
=> bar

If you’re shelling out longer commands, you might want to stream it as an IO object with popen or popen3. Both let you stream STDIN and STDOUT while popen3 adds STDERR:

IO.popen('sleep 10; echo home: $HOME') do |stream|
puts stream.gets until stream.eof?
=> home: /home/jscott

It’s worth noting that popen can actually stream a single command without using a shell which is usually a good idea when possible:

IO.popen(['echo', 'home: $HOME']) do |stream|
puts stream.gets until stream.eof?
=> home: $HOME

If you need an interactive process then you want to look at pty and shell. Unfortunately, these are more obscure and I’ve never had to use them so I’m just going going to link to someone who has. Best of luck!

With all the complexity of running commands in Ruby it’s kind of a wonder that I haven’t seen a gem for putting convention before configuration. Imagine a unified API that handles most of the above details for 80% of the use cases and exposes the nuance for those who need it.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.