简体   繁体   中英

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 figured 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

您可以使用“转义”库进行外壳转义,或者使用exec并将数组传递给它-如果这样做,则exec将使用SafeStringValue()宏自动转义

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM