модуль Shellwords
frozen-string-literal: true
Обрабатывает строки, как оболочка UNIX Bourne
Этот модуль обрабатывает строки в соответствии с правилами разбора слов оболочки UNIX Bourne.
Функция shellwords() первоначально была портирована из shellwords.pl, но была изменена для соответствия POSIX/SUSv3 (IEEE Std 1003.1-2001 [1]).
Использование
Вы можете использовать Shellwords для разбора строки в массив, удобный для оболочки Bourne.
require 'shellwords'
argv = Shellwords.split('three blind "mice"')
argv #=> ["three", "blind", "mice"]
После того, как вы подключили Shellwords, вы можете использовать псевдоним split String#shellsplit.
argv = "see how they run".shellsplit argv #=> ["see", "how", "they", "run"]
Будьте внимательны, чтобы не оставить незакрытой кавычку.
argv = "they all ran after the farmer's wife".shellsplit
#=> ArgumentError: Unmatched double quote: ...
В этом случае вы можете использовать ::escape или его псевдоним String#shellescape.
Этот метод позволит вам безопасно использовать строку с оболочкой Bourne, выполнив экранирование.
argv = Shellwords.escape("special's.txt")
argv #=> "special\\'s.txt"
system("cat " + argv)
Shellwords также поставляется с расширением для массивов Array#shelljoin.
argv = %w{ls -lta lib}
system(argv.shelljoin)
Вы можете использовать этот метод для создания экранированной строки из массива токенов, разделённых пробелом. В этом примере мы использовали сокращение для Array.new.
Авторы
-
Wakou Aoyama
-
Akinori MUSHA <knu@iDaemons.org>
Контакты
-
Akinori MUSHA <knu@iDaemons.org> (текущий ответственный)
Ресурсы
Общедоступные методы класса
# File lib/shellwords.rb, line 131 def shellescape(str) str = str.to_s # An empty argument will be skipped, so return empty quotes. return "''".dup if str.empty? str = str.dup # Treat multibyte characters as is. It is the caller's responsibility # to encode the string in the right encoding for the shell # environment. str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1") # A LF cannot be escaped with a backslash because a backslash + LF # combo is regarded as a line continuation and simply ignored. str.gsub!(/\n/, "'\n'") return str end
Экранирует строку, чтобы её можно было безопасно использовать в командной строке оболочки Bourne. str может быть объектом, не являющимся строкой, который отвечает на to_s.
Обратите внимание, что результирующую строку следует использовать без кавычек и она не предназначена для использования в двойных или одинарных кавычках.
argv = Shellwords.escape("It's better to give than to receive")
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
String#shellescape является сокращением для этой функции.
argv = "It's better to give than to receive".shellescape
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
# Search files in lib for method definitions
pattern = "^[ \t]*def "
open("| grep -Ern #{pattern.shellescape} lib") { |grep|
grep.each_line { |line|
file, lineno, matched_line = line.split(':', 3)
# ...
}
}
Ответственность за кодировку строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.
Многобайтовые символы обрабатываются как многобайтовые, а не как байты.
Возвращает пустую строку в кавычках, если str имеет длину ноль.
# File lib/shellwords.rb, line 177
def shelljoin(array)
array.map { |arg| shellescape(arg) }.join(' ')
end Создаёт строку командной строки из списка аргументов, array.
Все элементы объединяются в одну строку, поля разделяются пробелами, где каждый элемент экранируется для оболочки Bourne и преобразуется в строку с помощью to_s.
ary = ["There's", "a", "time", "and", "place", "for", "everything"] argv = Shellwords.join(ary) argv #=> "There\\'s a time and place for everything"
Array#shelljoin является сокращением для этой функции.
ary = ["Don't", "rock", "the", "boat"] argv = ary.shelljoin argv #=> "Don\\'t rock the boat"
Вы также можете смешивать объекты, не являющиеся строками, в элементах, как это разрешено в Array#join.
output = %x`#{['ps', '-p', $$].shelljoin}`
# File lib/shellwords.rb, line 78
def shellsplit(line)
words = []
field = String.new
line.scan(/\G\s*(?>([^\s\\\"]+)|'([^\]*)'|"((?:[^\"\]|\.)*)"|(\.?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
field << (word || sq || (dq || esc).gsub(/\(.)/, '\1'))
if sep
words << field
field = String.new
end
end
words
end Разделяет строку на массив токенов так же, как это делает оболочка UNIX Bourne.
argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]
Однако это не парсер командной строки. Символы мета-языка оболочки, кроме одинарных и двойных кавычек и обратной косой черты, не обрабатываются как таковые.
argv = Shellwords.split('ruby my_prog.rb | less')
argv #=> ["ruby", "my_prog.rb", "|", "less"]
String#shellsplit является сокращением для этой функции.
argv = 'here are "two words"'.shellsplit argv #=> ["here", "are", "two words"]
Закрытые методы экземпляра
# File lib/shellwords.rb, line 131 def shellescape(str) str = str.to_s # An empty argument will be skipped, so return empty quotes. return "''".dup if str.empty? str = str.dup # Treat multibyte characters as is. It is the caller's responsibility # to encode the string in the right encoding for the shell # environment. str.gsub!(/([^A-Za-z0-9_\-.,:\/@\n])/, "\\\\\\1") # A LF cannot be escaped with a backslash because a backslash + LF # combo is regarded as a line continuation and simply ignored. str.gsub!(/\n/, "'\n'") return str end
Экранирует строку, чтобы её можно было безопасно использовать в командной строке оболочки Bourne. str может быть объектом, не являющимся строкой, который отвечает на to_s.
Обратите внимание, что результирующую строку следует использовать без кавычек и она не предназначена для использования в двойных или одинарных кавычках.
argv = Shellwords.escape("It's better to give than to receive")
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
String#shellescape является сокращением для этой функции.
argv = "It's better to give than to receive".shellescape
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"
# Search files in lib for method definitions
pattern = "^[ \t]*def "
open("| grep -Ern #{pattern.shellescape} lib") { |grep|
grep.each_line { |line|
file, lineno, matched_line = line.split(':', 3)
# ...
}
}
Ответственность за кодировку строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.
Многобайтовые символы обрабатываются как многобайтовые, а не как байты.
Возвращает пустую строку в кавычках, если str имеет длину ноль.
# File lib/shellwords.rb, line 177
def shelljoin(array)
array.map { |arg| shellescape(arg) }.join(' ')
end Создаёт строку командной строки из списка аргументов, array.
Все элементы объединяются в одну строку, поля разделяются пробелами, где каждый элемент экранируется для оболочки Bourne и преобразуется в строку с помощью to_s.
ary = ["There's", "a", "time", "and", "place", "for", "everything"] argv = Shellwords.join(ary) argv #=> "There\\'s a time and place for everything"
Array#shelljoin является сокращением для этой функции.
ary = ["Don't", "rock", "the", "boat"] argv = ary.shelljoin argv #=> "Don\\'t rock the boat"
Вы также можете смешивать объекты, не являющиеся строками, в элементах, как это разрешено в Array#join.
output = %x`#{['ps', '-p', $$].shelljoin}`
# File lib/shellwords.rb, line 78
def shellsplit(line)
words = []
field = String.new
line.scan(/\G\s*(?>([^\s\\\"]+)|'([^\]*)'|"((?:[^\"\]|\.)*)"|(\.?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if garbage
field << (word || sq || (dq || esc).gsub(/\(.)/, '\1'))
if sep
words << field
field = String.new
end
end
words
end Разделяет строку на массив токенов так же, как это делает оболочка UNIX Bourne.
argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]
Однако это не парсер командной строки. Символы мета-языка оболочки, кроме одинарных и двойных кавычек и обратной косой черты, не обрабатываются как таковые.
argv = Shellwords.split('ruby my_prog.rb | less')
argv #=> ["ruby", "my_prog.rb", "|", "less"]
String#shellsplit является сокращением для этой функции.
argv = 'here are "two words"'.shellsplit argv #=> ["here", "are", "two words"]
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.