ruby-changes:2142
From: ko1@a...
Date: 5 Oct 2007 15:46:03 +0900
Subject: [ruby-changes:2142] knu - Ruby:r13633 (ruby_1_8): * lib/shellwords.rb: Add shellescape() and shelljoin().
knu 2007-10-05 15:45:33 +0900 (Fri, 05 Oct 2007) New Revision: 13633 Modified files: branches/ruby_1_8/lib/shellwords.rb Log: * lib/shellwords.rb: Add shellescape() and shelljoin(). * lib/shellwords.rb: Rename shellwords() to shellsplit() and make the former an alias to the latter. * lib/shellwords.rb: Add escape(), split(), join() as class methods, which are aliases to their respective long names prefixed with `shell'. * lib/shellwords.rb: Add String#shellescape(), String#shellsplit() and Array#shelljoin() for convenience. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/lib/shellwords.rb?r1=13633&r2=13632 Index: ruby_1_8/lib/shellwords.rb =================================================================== --- ruby_1_8/lib/shellwords.rb (revision 13632) +++ ruby_1_8/lib/shellwords.rb (revision 13633) @@ -1,31 +1,32 @@ # -# shellwords.rb: Split text into an array of tokens a la UNIX shell +# shellwords.rb: Manipulates strings a la UNIX Bourne shell # # -# This module is originally a port of shellwords.pl, but modified to -# conform to POSIX / SUSv3 (IEEE Std 1003.1-2001). +# This module manipulates strings according to the word parsing rules +# of the UNIX Bourne shell. # -# Examples: +# The shellwords() function was originally a port of shellwords.pl, +# but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001). # -# require 'shellwords' -# words = Shellwords.shellwords(line) +# Authors: +# - Wakou Aoyama +# - Akinori MUSHA <knu@i...> # -# or -# -# require 'shellwords' -# include Shellwords -# words = shellwords(line) -# module Shellwords - # - # Split text into an array of tokens in the same way the UNIX Bourne - # shell does. + # Splits a string into an array of tokens in the same way the UNIX + # Bourne shell does. # - # See the +Shellwords+ module documentation for an example. + # argv = Shellwords.split('here are "two words"') + # argv #=> ["here", "are", "two words"] # - def shellwords(line) + # +String#shellsplit+ is a shorthand for this function. + # + # argv = 'here are "two words"'.shellsplit + # argv #=> ["here", "are", "two words"] + # + def shellsplit(line) line = String.new(line) rescue raise(ArgumentError, "Argument must be a string") line.lstrip! @@ -56,5 +57,113 @@ words end - module_function :shellwords + alias shellwords shellsplit + + module_function :shellsplit, :shellwords + + class << self + alias split shellsplit + end + + # + # Escapes a string so that it can be safely used in a Bourne shell + # command line. + # + # Note that a resulted string should be used unquoted and is not + # intended for use in double quotes nor in single quotes. + # + # open("| grep #{Shellwords.escape(pattern)} file") { |pipe| + # # ... + # } + # + # +String#shellescape+ is a shorthand for this function. + # + # open("| grep #{pattern.shellescape} file") { |pipe| + # # ... + # } + # + def shellescape(str) + # An empty argument will be skipped, so return empty quotes. + return "''" if str.empty? + + str = str.dup + + # Process as a single byte sequence because not all shell + # implementations are multibyte aware. + str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1") + + # A LF cannot be escaped with a backslash because a backslash + LF + # combo is regarded as line continuation and simply ignored. + str.gsub!(/\n/, "'\n'") + + return str + end + + module_function :shellescape + + class << self + alias escape shellsplit + end + + # + # Builds a command line string from an argument list +array+ joining + # all elements escaped for Bourne shell and separated by a space. + # + # open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe| + # # ... + # } + # + # +Array#shelljoin+ is a shorthand for this function. + # + # open('|' + ['grep', pattern, *files].shelljoin) { |pipe| + # # ... + # } + # + def shelljoin(array) + array.map { |arg| shellescape(arg) }.join(' ') + end + + module_function :shelljoin + + class << self + alias join shelljoin + end end + +class String + # + # call-seq: + # str.shellsplit => array + # + # Splits +str+ into an array of tokens in the same way the UNIX + # Bourne shell does. See +Shellwords::shellsplit+ for details. + # + def shellsplit + Shellwords.split(self) + end + + # + # call-seq: + # str.shellescape => string + # + # Escapes +str+ so that it can be safely used in a Bourne shell + # command line. See +Shellwords::shellescape+ for details. + # + def shellescape + Shellwords.escape(self) + end +end + +class Array + # + # call-seq: + # array.shelljoin => string + # + # Builds a command line string from an argument list +array+ joining + # all elements escaped for Bourne shell and separated by a space. + # See +Shellwords::shelljoin+ for details. + # + def shelljoin + Shellwords.join(self) + end +end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml