2 # shellwords.rb: Manipulates strings a la UNIX Bourne shell
6 # This module manipulates strings according to the word parsing rules
7 # of the UNIX Bourne shell.
9 # The shellwords() function was originally a port of shellwords.pl,
10 # but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
14 # - Akinori MUSHA <knu@iDaemons.org>
17 # - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
21 # Splits a string into an array of tokens in the same way the UNIX
24 # argv = Shellwords.split('here are "two words"')
25 # argv #=> ["here", "are", "two words"]
27 # +String#shellsplit+ is a shorthand for this function.
29 # argv = 'here are "two words"'.shellsplit
30 # argv #=> ["here", "are", "two words"]
35 line.scan(/\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|\\.)*)"|(\\.?)|(\S))(\s|\z)?/m) do
36 |word, sq, dq, esc, garbage, sep|
37 raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
38 field << (word || sq || (dq || esc).gsub(/\\(?=.)/, ''))
47 alias shellwords shellsplit
49 module_function :shellsplit, :shellwords
52 alias split shellsplit
56 # Escapes a string so that it can be safely used in a Bourne shell
59 # Note that a resulted string should be used unquoted and is not
60 # intended for use in double quotes nor in single quotes.
62 # open("| grep #{Shellwords.escape(pattern)} file") { |pipe|
66 # +String#shellescape+ is a shorthand for this function.
68 # open("| grep #{pattern.shellescape} file") { |pipe|
73 # An empty argument will be skipped, so return empty quotes.
74 return "''" if str.empty?
78 # Process as a single byte sequence because not all shell
79 # implementations are multibyte aware.
80 str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
82 # A LF cannot be escaped with a backslash because a backslash + LF
83 # combo is regarded as line continuation and simply ignored.
84 str.gsub!(/\n/, "'\n'")
89 module_function :shellescape
92 alias escape shellescape
96 # Builds a command line string from an argument list +array+ joining
97 # all elements escaped for Bourne shell and separated by a space.
99 # open('|' + Shellwords.join(['grep', pattern, *files])) { |pipe|
103 # +Array#shelljoin+ is a shorthand for this function.
105 # open('|' + ['grep', pattern, *files].shelljoin) { |pipe|
110 array.map { |arg| shellescape(arg) }.join(' ')
113 module_function :shelljoin
123 # str.shellsplit => array
125 # Splits +str+ into an array of tokens in the same way the UNIX
126 # Bourne shell does. See +Shellwords::shellsplit+ for details.
129 Shellwords.split(self)
134 # str.shellescape => string
136 # Escapes +str+ so that it can be safely used in a Bourne shell
137 # command line. See +Shellwords::shellescape+ for details.
140 Shellwords.escape(self)
147 # array.shelljoin => string
149 # Builds a command line string from an argument list +array+ joining
150 # all elements escaped for Bourne shell and separated by a space.
151 # See +Shellwords::shelljoin+ for details.
154 Shellwords.join(self)