tags:

views:

69

answers:

2

I have a script that can be called by untrusted users, we need to make a call along the lines of this made up example:

system 'somescript ' + data

We need to ensure if data == 'filename; dosomethingelse' then the ; is escaped (or any other special character. The result is the shell command run is actually somescript filename\;\ dosomethingelse or somescript "filename; dosomethingelse"

Is there a standard way to do this?

+5  A: 
system 'somescript', data

Multi-argument calls to system are not passed to the shell for processing.

Chris Jester-Young
On a completely different note, it reminds me of questions where people ask how to escape strings so they're safe for use as an SQL string literal...the correct answer is "don't"; prepared statements are the correct way to go. In the same way, the correct way to make strings safe as program arguments is to not let them near the shell. :-P
Chris Jester-Young
Or how to parse HTML using regexes. http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454
Andrew Grimm
+1  A: 

The Shellwords module (part of the standard library) will do the appropriate escaping for shell commands:

#!/usr/bin/ruby1.8

require 'shellwords'

command = ['cat', 'filename with spaces', '"quoted_filename"'].shelljoin
puts command    # => cat filename\ with\ spaces \"quoted_filename\"
system(command)
# => this file has spaces in its name
# => this file has a quoted filename

shellwords also adds a shellescape method to String.

These methods are not in the online API documentation. They are partially documented in the 1.9 Pickaxe, and are known to be present in MRI 1.8.7. The actual file (on my box, in /usr/lib/ruby/1.8/shelljoin.rb) is well commented.

Wayne Conrad