Ruby escape ARGV argument or string as argument to shell command

后端 未结 3 549
情话喂你
情话喂你 2021-02-05 04:02

Ok this is driving me crazy:

`ls #{\"/media/music/Miles Davis\"}`

fails because of the space between \"Miles\" and \"Davis\"

Say I writ

相关标签:
3条回答
  • 2021-02-05 04:39

    Use require 'shellwords' and Shellwords.escape, which will fix this sort of stuff for you:

    http://apidock.com/ruby/Shellwords/shellescape

    0 讨论(0)
  • 2021-02-05 04:40

    Double quotes also works:

    `ls "#{'/media/music/Miles Davis'}"`
    

    or

    `ls "#{ARGV[0]}"`
    
    0 讨论(0)
  • 2021-02-05 04:57

    Stay away from building shell strings

    This is a fine vector for arbitrary code execution.

    In this case, you could use popen, which does the escaping for you, e.g.:

    #!/usr/bin/env ruby
    IO.popen(['printf', 'a b']) do |f|
      puts f.read
    end
    

    This outputs:

    a b
    

    just as if we had run on the terminal:

    /usr/bin/printf 'a b'
    

    If a b hadn't been escaped, we wouldn't get a b as expected, because running an unquoted:

    /usr/bin/printf a b
    

    in the terminal gives:

    a/usr/bin/printf: warning: ignoring excess arguments, starting with ‘b’
    

    Tested in Ubuntu 20.02, Ruby 2.6.

    0 讨论(0)
提交回复
热议问题