Getting output of system() calls in Ruby
Be aware that all the solutions where you pass a string containing user provided values to system
, %x[]
etc. are unsafe! Unsafe actually means: the user may trigger code to run in the context and with all permissions of the program.
As far as I can say only system
and Open3.popen3
do provide a secure/escaping variant in Ruby 1.8. In Ruby 1.9 IO::popen
also accepts an array.
Simply pass every option and argument as an array to one of these calls.
If you need not just the exit status but also the result you probably want to use Open3.popen3
:
require 'open3'
stdin, stdout, stderr, wait_thr = Open3.popen3('usermod', '-p', @options['shadow'], @options['username'])
stdout.gets(nil)
stdout.close
stderr.gets(nil)
stderr.close
exit_code = wait_thr.value
Note that the block form will auto-close stdin, stdout and stderr- otherwise they'd have to be closed explicitly.
More information here: Forming sanitary shell commands or system calls in Ruby
I'd like to expand & clarify chaos's answer a bit.
If you surround your command with backticks, then you don't need to (explicitly) call system() at all. The backticks execute the command and return the output as a string. You can then assign the value to a variable like so:
output = `ls`
p output
or
printf output # escapes newline chars