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