Ok this is driving me crazy:
`ls #{\"/media/music/Miles Davis\"}`
fails because of the space between \"Miles\" and \"Davis\"
Say I writ
Use require 'shellwords'
and Shellwords.escape
, which will fix this sort of stuff for you:
http://apidock.com/ruby/Shellwords/shellescape
Double quotes also works:
`ls "#{'/media/music/Miles Davis'}"`
or
`ls "#{ARGV[0]}"`
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.