| Module | Shellwords |
| In: |
lib/shellwords.rb
|
This module manipulates strings according to the word parsing rules of the UNIX Bourne shell.
The shellwords() function was originally a port of shellwords.pl, but modified to conform to POSIX / SUSv3 (IEEE Std 1003.1-2001).
Authors:
- Wakou Aoyama - Akinori MUSHA <knu@iDaemons.org>
Contact:
- Akinori MUSHA <knu@iDaemons.org> (current maintainer)
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|
# ...
}
# File lib/shellwords.rb, line 88
88: def shellescape(str)
89: # An empty argument will be skipped, so return empty quotes.
90: return "''" if str.empty?
91:
92: str = str.dup
93:
94: # Process as a single byte sequence because not all shell
95: # implementations are multibyte aware.
96: str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1")
97:
98: # A LF cannot be escaped with a backslash because a backslash + LF
99: # combo is regarded as line continuation and simply ignored.
100: str.gsub!(/\n/, "'\n'")
101:
102: return str
103: 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|
# ...
}
# File lib/shellwords.rb, line 125
125: def shelljoin(array)
126: array.map { |arg| shellescape(arg) }.join(' ')
127: end
Splits a string into an array of tokens in the same way the UNIX Bourne shell does.
argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]
+String#shellsplit+ is a shorthand for this function.
argv = 'here are "two words"'.shellsplit argv #=> ["here", "are", "two words"]
# File lib/shellwords.rb, line 32
32: def shellsplit(line)
33: line = String.new(line) rescue
34: raise(ArgumentError, "Argument must be a string")
35: line.lstrip!
36: words = []
37: until line.empty?
38: field = ''
39: loop do
40: if line.sub!(/\A"(([^"\\]|\\.)*)"/, '') then
41: snippet = $1.gsub(/\\(.)/, '\1')
42: elsif line =~ /\A"/ then
43: raise ArgumentError, "Unmatched double quote: #{line}"
44: elsif line.sub!(/\A'([^']*)'/, '') then
45: snippet = $1
46: elsif line =~ /\A'/ then
47: raise ArgumentError, "Unmatched single quote: #{line}"
48: elsif line.sub!(/\A\\(.)?/, '') then
49: snippet = $1 || '\\'
50: elsif line.sub!(/\A([^\s\\'"]+)/, '') then
51: snippet = $1
52: else
53: line.lstrip!
54: break
55: end
56: field.concat(snippet)
57: end
58: words.push(field)
59: end
60: words
61: end