Escaping a Ruby String for TextMate's $DIALOG command
Calling regex gurus. I'm having some trouble right now with escaping a string in Ruby so that I can pass it into a command line utility using exec
, %x{}
or similar. The command line command is the TextMate dialog feature, which basically works like this (Run this as a shell script in TextMate.):
$DIALOG -mp "items=('string1','string2', 'string3');" RequestItem
but it can also use a nib file you specify like "path/to/my/nib/file.nib" So, I need to pass that whole command as a string to exec
command = <<string
$DIALOG -mp "items=('string1','string2', 'string3');" "path/to/my/nib/file.nib"
string
exec command
This works fine naturally. The problem that I am running into is that the components of the items array are determined programmatically, so I need to programmatically escape this string in a way that will pass it all to the $DIALOG
command properly.
So far, I have determined a need to escape single quotes, double quotes, and newline and tab characters. I've tried a ton of potential regular expression solutions but haven't yet been able to land on a reliable escaping mechanism. Basically, I need to fill in
class String
def escape_for_dialog
self
end
end
with the right self.gsub
calls that will escape the strings that I am putting into the parameters. So, let's assume my params are looked up at runtime, here's what I think I need to do using the same example above:
command = <<string
$DIALOG -mp "items=('#{item1.escape_for_dialog}', '#{item2.escape_for_dialog}', '#{item3.escape_for_dialog}');" "path/to/my/nib/file.nib"
string
exec command
I have figu开发者_StackOverflow中文版red out that the heredoc style helps with not having to remember to escape all the quotes, but the parameters are still problematic so I'm asking for someone better with string manipulation and regular expressions than I am to lend a hand at filling in that string method. I'll be most grateful! :)
String.inspect will escape delimiters & etc. in a way that makes shell happy:
itemlist = "(#{items.join(', ')})"
command = [
$DIALOG,
'-mp',
itemlist.inspect,
'path/to/my/nib/file.nib',
].join(' ')
system(command)
Sadly, the answer to this is much simpler than it would seem: TextMate has a Ruby method for it! TextMate.app/Contents/SharedSupport/Support/lib#e_sh
You can use the "escape" library to do shell escaping, or alternatively use exec
and pass arrays to it - if done so, exec
will auto-escape using the SafeStringValue() macro
精彩评论