Reputation: 1214
Does Ruby ship with a function/method to run a command and capture it's output without risking command injection.
For example:
out = `ls #{directory}`
would capture the output I want, but is insecure.
system("ls", directory)
is safer (as far as I know), but I can't capture it's output.
Is there some equivalent to Python's out = call(['ls', directory])
?
Edit for @Eric Duminil
irb(main):001:0> RUBY_DESCRIPTION
=> "ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-linux]"
irb(main):002:0> Shellwords
NameError: uninitialized constant Shellwords
from (irb):2
from /apollo/env/SDETools/ruby2.1.x/bin/irb:15:in `<main>'
irb(main):003:0> require "shellwords"
=> true
irb(main):004:0> Shellwords
=> Shellword
Upvotes: 1
Views: 193
Reputation: 54223
You can escape the argument with Shellwords#shellescape
:
Escapes a string so that it can be safely used in a Bourne shell command line. str can be a non-string object that responds to to_s.
Note that a resulted string should be used unquoted and is not intended for use in double quotes nor in single quotes.
require 'shellwords' # <- Only needed for Ruby 1.9
"ls %s" % Shellwords.escape("test.txt && whoami")
# => "ls test.txt\\ \\&\\&\\ whoami"
system("ls %s" % Shellwords.escape("test.txt && whoami"))
# ls: cannot access test.txt && whoami: No such file or directory
As mentioned by @engineersmnky in the comments, you could simply use system
with multiple arguments:
system("ls", "test.txt && whoami")
# ls: cannot access test.txt && whoami: No such file or directory
Upvotes: 1