модуль Shellwords
Обрабатывает строки, как оболочка UNIX Bourne
Этот модуль обрабатывает строки в соответствии с правилами разбора слов оболочки UNIX Bourne.
Функция shellwords() изначально была портом shellwords.pl, но была модифицирована для соответствия разделу «Оболочки и утилиты» стандарта IEEE Std 1003.1-2008, издание 2016 года.
Использование
Вы можете использовать Shellwords для разбора строки в массив, совместимый с оболочкой Bourne Array.
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"]
Они обрабатывают кавычки как специальные символы, поэтому несовпадающая кавычка вызовет ArgumentError.
argv = "they all ran after the farmer's wife".shellsplit
#=> ArgumentError: Unmatched quote: ...
Shellwords также предоставляет методы, выполняющие обратную операцию. Shellwords.escape, или его псевдоним, String#shellescape, экранирует символы метаязыка оболочки в строке для использования в командной строке.
filename = "special's.txt"
system("cat -- #{filename.shellescape}")
# runs "cat -- special\\'s.txt"
Обратите внимание на символ ‘–’. Без него cat(1) будет обрабатывать следующий аргумент как опцию командной строки, если он начинается с ‘-’. Гарантируется, что Shellwords.escape преобразует строку в форму, которую оболочка Bourne разобьёт обратно в исходную строку, но программисту необходимо убедиться, что передача произвольного аргумента команде не приведёт к негативным последствиям.
Shellwords также поставляется с расширением ядра для Array, Array#shelljoin.
dir = "Funny GIFs"
argv = %W[ls -lta -- #{dir}]
system(argv.shelljoin + " | less")
# runs "ls -lta -- Funny\\ GIFs | less"
Вы можете использовать этот метод для построения полной командной строки из массива аргументов.
Авторы
-
Wakou Aoyama
-
Akinori MUSHA <knu@iDaemons.org>
Контакты
-
Akinori MUSHA <knu@iDaemons.org> (текущий разработчик)
Константы
- VERSION
-
Строка с номером версии.
Методы публичного класса
Исходный код
# File lib/shellwords.rb, line 158
def shellescape(str)
str = str.to_s
# An empty argument will be skipped, so return empty quotes.
return "''".dup if str.empty?
# Shellwords cannot contain NUL characters.
raise ArgumentError, "NUL character" if str.index("\0")
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]/, "\\\\\\&")
# 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.
str не должна содержать символов NUL из-за особенностей системного вызова exec.
Обратите внимание, что полученная строка должна использоваться без кавычек и не предназначена для использования в двойных кавычках или одинарных кавычках.
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 -e #{pattern.shellescape} lib") { |grep|
grep.each_line { |line|
file, lineno, matched_line = line.split(':', 3)
# ...
}
}
Ответственность за кодирование строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.
Многобайтовые символы обрабатываются как многобайтовые, а не как байты.
Возвращает пустую строку с кавычками String, если у str длина равна нулю.
Исходный код
# File lib/shellwords.rb, line 208
def shelljoin(array)
array.map { |arg| shellescape(arg) }.join(' ')
end Строит строку командной строки из списка аргументов, array.
Все элементы объединяются в одну строку с полями, разделёнными пробелами, где каждый элемент экранируется для оболочки Bourne и строит строкой с помощью to_s. Смотрите также Shellwords.shellescape.
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 = `#{['ps', '-p', $$].shelljoin}`
Исходный код
# File lib/shellwords.rb, line 90
def shellsplit(line)
words = []
field = String.new
line.scan(/\G\s*(?>([^\0\s\\\'\"]+)|'([^\0\']*)'|"((?:[^\0\"\\]|\\[^\0])*)"|(\\[^\0]?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
if garbage
b = $~.begin(0)
line = $~[0]
line = "..." + line if b > 0
raise ArgumentError, "#{garbage == "\0" ? 'Nul character' : 'Unmatched quote'} at #{b}: #{line}"
end
# 2.2.3 Double-Quotes:
#
# The <backslash> shall retain its special meaning as an
# escape character only when followed by one of the following
# characters when considered special:
#
# $ ` " \ <newline>
field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1'))
if sep
words << field
field = String.new
end
end
words
end Разделяет строку на массив токенов так же, как это делает оболочка Bourne UNIX.
argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]
line не должна содержать символов NUL из-за особенностей системного вызова exec.
Обратите внимание, что это не анализатор командной строки. Метасимволы оболочки, кроме одинарных и двойных кавычек и обратной косой черты, не обрабатываются как таковые.
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 158
def shellescape(str)
str = str.to_s
# An empty argument will be skipped, so return empty quotes.
return "''".dup if str.empty?
# Shellwords cannot contain NUL characters.
raise ArgumentError, "NUL character" if str.index("\0")
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]/, "\\\\\\&")
# 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.
str не должна содержать символов NUL из-за особенностей системного вызова exec.
Обратите внимание, что полученная строка должна использоваться без кавычек и не предназначена для использования в двойных кавычках или одинарных кавычках.
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 -e #{pattern.shellescape} lib") { |grep|
grep.each_line { |line|
file, lineno, matched_line = line.split(':', 3)
# ...
}
}
Ответственность за кодирование строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.
Многобайтовые символы обрабатываются как многобайтовые, а не как байты.
Возвращает пустую строку с кавычками String, если у str длина равна нулю.
Исходный код
# File lib/shellwords.rb, line 208
def shelljoin(array)
array.map { |arg| shellescape(arg) }.join(' ')
end Строит строку командной строки из списка аргументов, array.
Все элементы объединяются в одну строку с полями, разделёнными пробелами, где каждый элемент экранируется для оболочки Bourne и строит строкой с помощью to_s. Смотрите также Shellwords.shellescape.
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 = `#{['ps', '-p', $$].shelljoin}`
Исходный код
# File lib/shellwords.rb, line 90
def shellsplit(line)
words = []
field = String.new
line.scan(/\G\s*(?>([^\0\s\\\'\"]+)|'([^\0\']*)'|"((?:[^\0\"\\]|\\[^\0])*)"|(\\[^\0]?)|(\S))(\s|\z)?/m) do
|word, sq, dq, esc, garbage, sep|
if garbage
b = $~.begin(0)
line = $~[0]
line = "..." + line if b > 0
raise ArgumentError, "#{garbage == "\0" ? 'Nul character' : 'Unmatched quote'} at #{b}: #{line}"
end
# 2.2.3 Double-Quotes:
#
# The <backslash> shall retain its special meaning as an
# escape character only when followed by one of the following
# characters when considered special:
#
# $ ` " \ <newline>
field << (word || sq || (dq && dq.gsub(/\\([$`"\\\n])/, '\\1')) || esc.gsub(/\\(.)/, '\\1'))
if sep
words << field
field = String.new
end
end
words
end Разделяет строку на массив токенов так же, как это делает оболочка Bourne UNIX.
argv = Shellwords.split('here are "two words"')
argv #=> ["here", "are", "two words"]
line не должна содержать символов NUL из-за особенностей системного вызова exec.
Обратите внимание, что это не анализатор командной строки. Метасимволы оболочки, кроме одинарных и двойных кавычек и обратной косой черты, не обрабатываются как таковые.
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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.