Module: Bio::Command
- Defined in:
- lib/bio/command.rb
Overview
Bio::Command
Bio::Command is a collection of useful methods for execution of external commands or web applications. Any wrapper class for applications shall use this class.
Library internal use only. Users should not directly use it.
Constant Summary collapse
- UNSAFE_CHARS_UNIX =
/[^A-Za-z0-9\_\-\.\:\,\/\@\x1b\x80-\xfe]/n
- QUOTE_CHARS_WINDOWS =
/[^A-Za-z0-9\_\-\.\:\,\/\@\\]/n
- UNESCAPABLE_CHARS =
/[\x00-\x08\x10-\x1a\x1c-\x1f\x7f\xff]/n
Class Method Summary collapse
-
.call_command(cmd, &block) ⇒ Object
Executes the program.
-
.call_command_fork(cmd) ⇒ Object
Executes the program via fork (by using IO.popen(“-”)) and exec.
-
.call_command_open3(cmd) ⇒ Object
Executes the program via Open3.popen3 A block must be given.
-
.call_command_popen(cmd) ⇒ Object
Executes the program via IO.popen for OS which doesn’t support fork.
-
.escape_shell(str) ⇒ Object
Escape special characters in command line string.
-
.escape_shell_unix(str) ⇒ Object
Escape special characters in command line string for UNIX shells.
-
.escape_shell_windows(str) ⇒ Object
Escape special characters in command line string for cmd.exe on Windows.
- .make_cgi_params(params) ⇒ Object
- .make_cgi_params_key_value(key, value) ⇒ Object
-
.make_command_line(ary) ⇒ Object
Generate command line string with special characters escaped.
-
.make_command_line_unix(ary) ⇒ Object
Generate command line string with special characters escaped for UNIX shells.
-
.make_command_line_windows(ary) ⇒ Object
Generate command line string with special characters escaped for cmd.exe on Windows.
-
.new_http(address, port = 80) ⇒ Object
Same as: Net::HTTP.new(address, port) and it uses proxy if an environment variable (same as OpenURI.open_uri) is set.
-
.post_form(uri, params = nil, header = {}) ⇒ Object
Same as: Net::HTTP.post_form(uri, params) and it uses proxy if an environment variable (same as OpenURI.open_uri) is set.
-
.query_command(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
-
.query_command_fork(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
-
.query_command_open3(cmd, query = nil) ⇒ Object
Executes the program via Open3.popen3 with the query (String) given to the stain, waits the program termination, and returns the data from stdout and stderr as an array of the strings.
-
.query_command_popen(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
-
.read_uri(uri) ⇒ Object
Same as OpenURI.open_uri(uri).read.
-
.start_http(address, port = 80, &block) ⇒ Object
Same as: Net::HTTP.start(address, port) and it uses proxy if an environment variable (same as OpenURI.open_uri) is set.
Class Method Details
.call_command(cmd, &block) ⇒ Object
Executes the program. Automatically select popen for Windows environment and fork for the others. A block must be given. An IO object is passed to the block.
87 88 89 90 91 92 93 94 |
# File 'lib/bio/command.rb', line 87 def call_command(cmd, &block) case RUBY_PLATFORM when /mswin32|bccwin32/ call_command_popen(cmd, &block) else call_command_fork(cmd, &block) end end |
.call_command_fork(cmd) ⇒ Object
Executes the program via fork (by using IO.popen(“-”)) and exec. A block must be given. An IO object is passed to the block.
From the view point of security, this method is recommended rather than call_command_popen.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/bio/command.rb', line 111 def call_command_fork(cmd) IO.popen("-", "r+") do |io| if io then # parent yield io else # child begin Kernel.exec(*cmd) rescue Errno::ENOENT, Errno::EACCES Process.exit!(127) rescue Exception end Process.exit!(1) end end end |
.call_command_open3(cmd) ⇒ Object
Executes the program via Open3.popen3 A block must be given. IO objects are passed to the block.
You would use this method only when you really need to get stderr.
133 134 135 136 137 138 |
# File 'lib/bio/command.rb', line 133 def call_command_open3(cmd) cmd = cmd.collect { |x| x.to_s } Open3.popen3(*cmd) do |pin, pout, perr| yield pin, pout, perr end end |
.call_command_popen(cmd) ⇒ Object
Executes the program via IO.popen for OS which doesn’t support fork. A block must be given. An IO object is passed to the block.
98 99 100 101 102 103 104 |
# File 'lib/bio/command.rb', line 98 def call_command_popen(cmd) str = make_command_line(cmd) IO.popen(str, "w+") do |io| io.sync = true yield io end end |
.escape_shell(str) ⇒ Object
Escape special characters in command line string.
53 54 55 56 57 58 59 60 |
# File 'lib/bio/command.rb', line 53 def escape_shell(str) case RUBY_PLATFORM when /mswin32|bccwin32/ escape_shell_windows(str) else escape_shell_unix(str) end end |
.escape_shell_unix(str) ⇒ Object
Escape special characters in command line string for UNIX shells.
46 47 48 49 50 |
# File 'lib/bio/command.rb', line 46 def escape_shell_unix(str) str = str.to_s raise 'cannot escape control characters' if UNESCAPABLE_CHARS =~ str str.gsub(UNSAFE_CHARS_UNIX) { |x| "\\#{x}" } end |
.escape_shell_windows(str) ⇒ Object
Escape special characters in command line string for cmd.exe on Windows.
35 36 37 38 39 40 41 42 43 |
# File 'lib/bio/command.rb', line 35 def escape_shell_windows(str) str = str.to_s raise 'cannot escape control characters' if UNESCAPABLE_CHARS =~ str if QUOTE_CHARS_WINDOWS =~ str then '"' + str.gsub(/\"/, '""') + '"' else String.new(str) end end |
.make_cgi_params(params) ⇒ Object
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/bio/command.rb', line 292 def make_cgi_params(params) data = "" case params when Hash data = params.map do |key, val| make_cgi_params_key_value(key, val) end.join('&') when Array case params.first when Hash data = params.map do |hash| hash.map do |key, val| make_cgi_params_key_value(key, val) end end.join('&') when Array data = params.map do |key, val| make_cgi_params_key_value(key, val) end.join('&') when String data = params.map do |str| URI.escape(str.strip) end.join('&') end when String data = URI.escape(params.strip) end return data end |
.make_cgi_params_key_value(key, value) ⇒ Object
322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/bio/command.rb', line 322 def make_cgi_params_key_value(key, value) result = [] case value when Array value.each do |val| result << [key, val].map {|x| URI.escape(x.to_s) }.join('=') end else result << [key, value].map {|x| URI.escape(x.to_s) }.join('=') end return result end |
.make_command_line(ary) ⇒ Object
Generate command line string with special characters escaped.
63 64 65 66 67 68 69 70 |
# File 'lib/bio/command.rb', line 63 def make_command_line(ary) case RUBY_PLATFORM when /mswin32|bccwin32/ make_command_line_windows(ary) else make_command_line_unix(ary) end end |
.make_command_line_unix(ary) ⇒ Object
Generate command line string with special characters escaped for UNIX shells.
80 81 82 |
# File 'lib/bio/command.rb', line 80 def make_command_line_unix(ary) ary.collect { |str| escape_shell_unix(str) }.join(" ") end |
.make_command_line_windows(ary) ⇒ Object
Generate command line string with special characters escaped for cmd.exe on Windows.
74 75 76 |
# File 'lib/bio/command.rb', line 74 def make_command_line_windows(ary) ary.collect { |str| escape_shell_windows(str) }.join(" ") end |
.new_http(address, port = 80) ⇒ Object
Same as:
Net::HTTP.new(address, port)
and it uses proxy if an environment variable (same as OpenURI.open_uri) is set.
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/bio/command.rb', line 251 def new_http(address, port = 80) uri = URI.parse("http://#{address}:#{port}") # Note: URI#find_proxy is an unofficial method defined in open-uri.rb. # If the spec of open-uri.rb would be changed, we should change below. if proxyuri = uri.find_proxy then raise 'Non-HTTP proxy' if proxyuri.class != URI::HTTP Net::HTTP.new(address, port, proxyuri.host, proxyuri.port) else Net::HTTP.new(address, port) end end |
.post_form(uri, params = nil, header = {}) ⇒ Object
Same as: Net::HTTP.post_form(uri, params) and it uses proxy if an environment variable (same as OpenURI.open_uri) is set. In addition, header
can be set. (Note that Content-Type and Content-Length are automatically set by default.) uri
must be a URI object, params
must be a hash, and header
must be a hash.
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/bio/command.rb', line 274 def post_form(uri, params = nil, header = {}) unless uri.is_a?(URI) uri = URI.parse(uri) end data = make_cgi_params(params) hash = { 'Content-Type' => 'application/x-www-form-urlencoded', 'Content-Length' => data.length.to_s } hash.update(header) start_http(uri.host, uri.port) do |http| http.post(uri.path, data, hash) end end |
.query_command(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
Automatically select popen for Windows environment and fork for the others.
145 146 147 148 149 150 151 152 |
# File 'lib/bio/command.rb', line 145 def query_command(cmd, query = nil) case RUBY_PLATFORM when /mswin32|bccwin32/ query_command_popen(cmd, query) else query_command_fork(cmd, query) end end |
.query_command_fork(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
Fork (by using IO.popen(“-”)) and exec is used to execute the program.
From the view point of security, this method is recommended rather than query_popen.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/bio/command.rb', line 177 def query_command_fork(cmd, query = nil) IO.popen("-", "r+") do |io| if io then # parent io.sync = true io.print query if query io.close_write io.read else # child begin Kernel.exec(*cmd) rescue Errno::ENOENT, Errno::EACCES Process.exit!(127) rescue Exception end Process.exit!(1) end end end |
.query_command_open3(cmd, query = nil) ⇒ Object
Executes the program via Open3.popen3 with the query (String) given to the stain, waits the program termination, and returns the data from stdout and stderr as an array of the strings.
From the view point of security, this method is recommended rather than exec_local_popen.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/bio/command.rb', line 204 def query_command_open3(cmd, query = nil) errorlog = nil cmd = cmd.collect { |x| x.to_s } Open3.popen3(*cmd) do |pin, pout, perr| perr.sync = true t = Thread.start { errorlog = perr.read } begin pin.print query if query pin.close output = pout.read ensure t.join end [ output, errorlog ] end end |
.query_command_popen(cmd, query = nil) ⇒ Object
Executes the program with the query (String) given to the standard input, waits the program termination, and returns the output data printed to the standard output as a string.
IO.popen is used for OS which doesn’t support fork.
159 160 161 162 163 164 165 166 167 |
# File 'lib/bio/command.rb', line 159 def query_command_popen(cmd, query = nil) str = make_command_line(cmd) IO.popen(str, "w+") do |io| io.sync = true io.print query if query io.close_write io.read end end |
.read_uri(uri) ⇒ Object
Same as OpenURI.open_uri(uri).read.
222 223 224 |
# File 'lib/bio/command.rb', line 222 def read_uri(uri) OpenURI.open_uri(uri).read end |
.start_http(address, port = 80, &block) ⇒ Object
Same as:
Net::HTTP.start(address, port)
and it uses proxy if an environment variable (same as OpenURI.open_uri) is set.
232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/bio/command.rb', line 232 def start_http(address, port = 80, &block) uri = URI.parse("http://#{address}:#{port}") # Note: URI#find_proxy is an unofficial method defined in open-uri.rb. # If the spec of open-uri.rb would be changed, we should change below. if proxyuri = uri.find_proxy then raise 'Non-HTTP proxy' if proxyuri.class != URI::HTTP http = Net::HTTP.Proxy(proxyuri.host, proxyuri.port) else http = Net::HTTP end http.start(address, port, &block) end |