Execute a shell script in Ruby passing HTML/PHP code as an argument

231 views Asked by At

I've got a HTML/PHP code that I pass through a Ruby function. I want it to render a minified PHP rather than just as is. I recon that the shell command php -w would be perfect to do so.

module Haml
  module Filters
    module PHP
      include Base
      ##
      # @param text, string (Haml/PHP code)
      #
      def render(text)

         `php -w <<< "<?php #{text} ?>"`

      end
    end
  end
end

The above code breaks because the HTML/PHP string text contains special characters. What is best way of escaping them?


After posting this question and thanks to comments I did more trial and error.

I established it is caused by only four special characters: " \ $ (backtick) (double quote, backward slash, dollar sign, backtick)

I created a simple solution that works (below).

3

There are 3 answers

4
KickinEspresso On

Have you looked at this answer: Ruby: Escaping special characters in a string

it sounds like that after you've read your file in, you need to strip out the characters.

file = File.open("users.txt")
file_data = file.read
clean_data = file_data.gsub(/\\/, '')

Then print your data to the shell command (You may to do some more escaping)

0
Maciek Rek On

The below substitution chain seems to work, but as some people pointed out a possible better solution would be using shellescape.

# a breakdown of escaped characters

text.gsub("\\", "\\\\\\")  #   \ backslash (the escape character) 
text.gsub("\"", "\\\"")    #   " double quotation mark
text.gsub("$", "\\$")      #   $ dollar sign
text.gsub("`", "\\\\`")    #   ` backtick

Amended code

module Haml
  module Filters
    module PHP
      include Base
      def render(text)

         text=text.gsub("\\", "\\\\\\").gsub("\"", "\\\"").gsub("$", "\\$").gsub("`", "\\\\`")

         `php -w <<< "<?php #{text} ?>"`

      end
    end
  end
end
1
tadman On

Passing content in on the command line is not just risky, but the wrong way to do it in the first place. Use tools like Open3 to do it by streaming it in directly which avoids the need for escaping altogether.

Feed the input to the STDIN filehandle of your php -w process:

output = ''

Open3.popen2('php', '-w') do |stdin, stdout, wait_thr|
  stdin.write("<?php #{text} ?>")
  stdin.close
  output << stdout.read
end