Spec-Zone.ru › Ruby 3.3

модуль Shellwords

Обрабатывает строки, как оболочка UNIX Bourne

Этот модуль обрабатывает строки в соответствии с правилами разбора слов оболочки UNIX Bourne.

Функция shellwords() изначально была портирована из shellwords.pl, но была изменена, чтобы соответствовать разделу «Оболочка и утилиты» стандарта IEEE Std 1003.1-2008, издание 2016 г. [1].

Использование

Вы можете использовать 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> (текущий администратор)

Ссылки

1: IEEE Std 1003.1-2008, 2016 Edition, раздел «Оболочка и утилиты»

Константы

VERSION

Публичные методы класса

escape(str)
Псевдоним для: shellescape
join(array)
Псевдоним для: shelljoin
shellescape(str) Показать исходный код
# File lib/shellwords.rb, line 150
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]/, "\\\\\\&")

  # 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 -e #{pattern.shellescape} lib") { |grep|
  grep.each_line { |line|
    file, lineno, matched_line = line.split(':', 3)
    # ...
  }
}

Ответственность за кодирование строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.

Многобайтовые символы обрабатываются как многобайтовые, а не как байты.

Возвращает пустую строку с кавычками String, если длина str равна нулю.

Также алиас для: escape
shelljoin(array) Показать исходный код
# File lib/shellwords.rb, line 196
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 = `#{['ps', '-p', $$].shelljoin}`
Также алиас для: join
shellsplit(line) Показать исходный код
# File lib/shellwords.rb, line 90
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 quote: #{line.inspect}" if garbage
    # 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

Разделяет строку на массив токенов так же, как это делает оболочка 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"]
Также алиас для: shellwords, split
shellwords(line)
Псевдоним для: shellsplit
split(line)
Псевдоним для: shellsplit

Приватные методы экземпляра

shellescape(str) Показать исходный код
# File lib/shellwords.rb, line 150
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]/, "\\\\\\&")

  # 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 -e #{pattern.shellescape} lib") { |grep|
  grep.each_line { |line|
    file, lineno, matched_line = line.split(':', 3)
    # ...
  }
}

Ответственность за кодирование строки в правильной кодировке для среды оболочки, где используется эта строка, лежит на вызывающей стороне.

Многобайтовые символы обрабатываются как многобайтовые, а не как байты.

Возвращает пустую строку с кавычками String, если длина str равна нулю.

Также алиас для: escape
shelljoin(array) Показать исходный код
# File lib/shellwords.rb, line 196
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 = `#{['ps', '-p', $$].shelljoin}`
Также алиас для: join
shellsplit(line) Показать исходный код
# File lib/shellwords.rb, line 90
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 quote: #{line.inspect}" if garbage
    # 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

Разделяет строку на массив токенов так же, как это делает оболочка 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"]
Также алиас для: shellwords, split
shellwords(line)
Псевдоним для: shellsplit

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API