РЕДАКТИРОВАТЬ: Пожалуйста, пожалуйста , пожалуйста, прочтите два требования, перечисленные внизу этого сообщения, прежде чем отвечать. Люди продолжают публиковать свои новые жемчужины, библиотеки и тому подобное, что явно не соответствует требованиям.
Иногда я хочу очень дешево превратить некоторые параметры командной строки в простой скрипт. Интересный способ сделать это без использования getopts, синтаксического анализа или чего-то подобного:
...
$quiet = ARGV.delete('-d')
$interactive = ARGV.delete('-i')
...
# Deal with ARGV as usual here, maybe using ARGF or whatever.
Это не совсем обычный синтаксис параметров Unix, потому что он принимает параметры, не являющиеся параметрами командной строки, как в " myprog -i foo bar -q
", но я могу с этим жить. (Некоторые люди, например разработчики Subversion, предпочитают это. Иногда я тоже.)
Вариант, который просто присутствует или отсутствует, не может быть реализован намного проще, чем описанный выше. (Одно присвоение, один вызов функции, один побочный эффект.) Есть ли столь же простой способ работать с параметрами, которые принимают параметр, например " -f
имя файла "?
РЕДАКТИРОВАТЬ:
Один момент, о котором я не говорил ранее, потому что мне не становилось ясно, пока автор Trollop не упомянул, что библиотека помещается «в один [800-строчный] файл», заключается в том, что я ищу не только чистый синтаксис, но для техники, имеющей следующие характеристики:
Весь код может быть включен в файл сценария (не перегружая сам сценарий, который может состоять всего из пары десятков строк), так что можно поместить один файл в каталог в
bin
любой системе со стандартным Ruby 1.8. . [5-7] установка и использование. Если вы не можете написать сценарий Ruby, в котором нет операторов require, а код для синтаксического анализа нескольких параметров занимает менее десятка строк или около того, вы не выполняете это требование.Код небольшой и достаточно простой, чтобы его можно было запомнить достаточно, чтобы напрямую ввести код, который сделает свое дело, а не вырезать и вставить где-то еще. Подумайте о ситуации, когда вы находитесь на консоли сервера, защищенного брандмауэром, без доступа к Интернету, и вы хотите быстро собрать сценарий для использования клиентом. Не знаю, как вы, но (помимо невыполнения указанного выше требования) запоминание даже 45 строк упрощенного micro-optparse - это не то, чем я хочу заниматься.
getoptlong
иoptparse
в стандартной библиотеке рубина, так что вам не нужно копировать их при развертывании сценария - если рубин работает на этой машине, тоrequire 'optparse'
илиrequire 'getoptlong'
тоже будет работать.Ответы:
Как автор Trollop , я не могу поверить в то, что люди считают разумным в парсере опций. Шутки в сторону. Это поражает воображение.
Зачем мне нужно делать модуль, расширяющий какой-либо другой модуль для анализа параметров? Зачем мне что-то подклассифицировать? Зачем мне нужно подписываться на какую-то «структуру» только для анализа командной строки?
Вот версия вышесказанного от Trollop:
И это все.
opts
Теперь хэш с ключами:quiet
,:interactive
и:filename
. Вы можете делать с ним все, что хотите. И вы получите красивую страницу справки, отформатированную под ширину экрана, автоматические короткие имена аргументов, проверку типов ... все, что вам нужно.Это один файл, поэтому вы можете поместить его в свой каталог lib /, если не хотите формальной зависимости. Он имеет минимальный DSL, который легко подобрать.
LOC на выбор людей. Это имеет значение.
источник
Я разделяю ваше отвращение
require 'getopts'
, в основном из-за того, чтоOptionParser
:источник
Вот стандартная техника, которую я обычно использую:
источник
lib
папку или код и использовать его, даже не касаясь rubygems.when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
на,when /^-/ then usage("Unknown option: #{ARGV.shift.inspect}")
иначеПоскольку никто не упомянул об этом, а заголовок действительно относится к дешевому синтаксическому анализу командной строки, почему бы просто не позволить интерпретатору Ruby сделать эту работу за вас? Если вы передадите
-s
переключатель (например, в вашем shebang), вы бесплатно получите простые переключатели, назначенные однобуквенным глобальным переменным. Вот ваш пример с использованием этого переключателя:И вот результат, когда я сохраняю это как
./test
и chmod+x
:Подробнее
ruby -h
см.Это должно быть максимально дешево. Он вызовет NameError, если вы попробуете переключить, например
-:
, так что там есть некоторая проверка. Конечно, у вас не может быть никаких переключателей после аргумента без переключателя, но если вам нужно что-то необычное, вам действительно стоит использовать как минимум OptionParser. Фактически, единственное, что меня раздражает в этой технике, это то, что вы получите предупреждение (если вы включили их) при доступе к неустановленной глобальной переменной, но оно все равно ложно, поэтому отлично работает для одноразовых инструментов и быстрого скрипты.Одно предостережение, указанное FelipeC в комментариях к статье « Как сделать действительно дешевый синтаксический анализ параметров командной строки в Ruby », заключается в том, что ваша оболочка может не поддерживать 3-токеновый шебанг; вам может потребоваться заменить
/usr/bin/env ruby -w
фактический путь к вашему рубину (например/usr/local/bin/ruby -w
) или запустить его из сценария-оболочки или что-то в этом роде.источник
Я создал micro-optparse, чтобы удовлетворить эту очевидную потребность в коротком, но простом в использовании парсере опций. Он имеет синтаксис, аналогичный Trollop, и состоит из 70 строк. Если вам не нужны проверки и можно обойтись без пустых строк, вы можете сократить его до 45 строк. Я думаю, это именно то, что вы искали.
Краткий пример:
Вызов скрипта с помощью
-h
или--help
распечатаетОн проверяет, имеет ли ввод тот же тип, что и значение по умолчанию, генерирует короткие и длинные методы доступа, печатает описательные сообщения об ошибках, если указаны недопустимые аргументы, и многое другое.
Я сравнил несколько парсеров опций , используя каждый парсер опций для моей проблемы. Вы можете использовать эти примеры и мое резюме, чтобы принять информативное решение. Не стесняйтесь добавлять в список другие реализации. :)
источник
optparse
что составляет (плюс-минус) 1937 строк.optparse
как это библиотека по умолчанию, то есть она поставляется с каждой установкой Ruby.Trollop
является сторонней библиотекой, поэтому вы должны импортировать полный код каждый раз, когда хотите включить его в проект. µ-optparse всегда требует только ~ 70 строк, поскольку ониoptparse
уже есть.Я полностью понимаю, почему вы хотите избежать optparse - его может оказаться слишком много. Но есть несколько гораздо более «легких» решений (по сравнению с OptParse), которые поставляются в виде библиотек, но достаточно просты, чтобы сделать установку одного гема оправданной.
Например, посмотрите этот пример OptiFlag . Всего несколько строк на обработку. Слегка усеченный пример для вашего случая:
Также существует масса индивидуальных примеров . Я помню, как использовал другой, который был еще проще, но пока он ускользнул от меня, но я вернусь и добавлю здесь комментарий, если найду его.
источник
Вот что я использую для действительно очень дешевых аргументов:
поэтому, если вы запустите,
programname foo bar
он вызовет foo, а затем bar. Это удобно для одноразовых скриптов.источник
Вы можете попробовать что-то вроде:
источник
Вы считали Тора викатами? Я думаю, что это намного чище, чем optparse. Если у вас уже есть сценарий, может потребоваться дополнительная работа по его форматированию или рефакторингу для tor, но это действительно упрощает работу с параметрами.
Вот пример фрагмента из README:
Тор автоматически отображает команды как таковые:
Это преобразуется в:
источник
--help
вывод? Что, если бы вывод справки был "head myprogram.rb"?Вот мой любимый парсер быстрых и грязных опций:
Параметры являются регулярными выражениями, поэтому "-h" также будет соответствовать "--help".
Читаемый, легко запоминающийся, без внешней библиотеки и минимальный код.
источник
/-h(\b|elp)
Троллоп стоит довольно дешево.
источник
Если вам нужен простой парсер командной строки для команд ключ / значение без использования драгоценных камней:
Но это работает, только если у вас всегда есть пары ключ / значение.
Если вам не нужна какая-либо проверка, вы можете просто использовать:
источник
Вот фрагмент кода, который я использую в верхней части большинства своих скриптов:
Я также ненавижу требовать дополнительных файлов в моих быстрых и грязных сценариях. Мое решение очень близко к тому, о чем вы просите. Я вставляю 10-строчный фрагмент кода в верхнюю часть любого из моих сценариев, который анализирует командную строку, вставляет позиционные аргументы и переключается на объект Hash (обычно назначаемый объекту, который я назвал arghash в примерах ниже).
Вот пример командной строки, которую вы можете захотеть проанализировать ...
Что станет таким хешем.
В дополнение к этому к хешу добавляются два удобных метода:
argc()
вернет количество непереключаемых аргументов.switches()
вернет массив, содержащий ключи для имеющихся переключателейЭто означает, что можно позволить некоторые быстрые и грязные вещи вроде ...
arghash.argc == 2
)arghash[1]
всегда получает второй аргумент без переключателя).arghash['--max=']
что дает значение «15» с учетом примера командной строки.arghash['-s']
которая принимает значение true, если он присутствует, и nil, если его нет.Проверьте наличие переключателя или альтернативных переключателей, используя операции установки, такие как
puts USAGETEXT if !(%w(-h --help) & arghash.switches()).empty?
Определите использование недопустимых переключателей, используя операции с наборами, такие как
puts "Invalid switch found!" if !(arghash.switches - %w(-valid1 -valid2)).empty?
Укажите значения по умолчанию для отсутствующих аргументов, используя простой
Hash.merge()
пример, такой как приведенный ниже пример, который заполняет значение для -max =, если он не был установлен, и добавляет 4-й позиционный аргумент, если он не был передан.with_defaults = {'-max=' => 20, 3 => 'default.txt'}.merge(arghash)
источник
=
) может повлиять на нужный вам код.Это очень похоже на принятый ответ, но
ARGV.delete_if
я использую его в своем простом парсере . Единственная реальная разница в том, что параметры с аргументами должны быть вместе (например-l=file
).источник
Очевидно, мы с @WilliamMorgan одинаково думаем. Вчера вечером я выпустил на Github библиотеку, похожую на Trollop (названную как?), После поиска OptionParser на Github, см. Переключатели.
Есть несколько отличий, но философия та же. Одно очевидное отличие состоит в том, что Switches зависит от OptionParser.
источник
Я разрабатываю свой собственный гем синтаксического анализатора под названием Acclaim .
Я написал его, потому что хотел создать интерфейсы командной строки в стиле git и иметь возможность четко разделить функциональность каждой команды на отдельные классы, но ее также можно использовать без всей командной структуры:
Стабильной версии пока нет, но я уже реализовал некоторые функции, такие как:
Большое внимание уделяется командам, поэтому для простого синтаксического анализа командной строки это может быть немного сложно, но оно работает хорошо, и я использовал его во всех своих проектах. Если вас интересует аспект командного интерфейса , посетите страницу проекта GitHub для получения дополнительной информации и примеров.
источник
Предположим, что у команды есть не более одного действия и произвольное количество опций, например:
Разбор без проверки может быть таким:
источник
https://github.com/soveran/clap
46LOC (в 1.0.0), нет зависимости от внешнего синтаксического анализатора параметров. Выполняет свою работу. Возможно, не так полнофункциональный, как другие, но это 46LOC.
Если вы проверите код, вы можете довольно легко продублировать базовый метод - назначить лямбды и использовать арность, чтобы обеспечить правильное количество аргументов, следующих за флагом, если вам действительно не нужна внешняя библиотека.
Просто. Дешевые.
РЕДАКТИРОВАТЬ : основная концепция сводится к тому, что, я полагаю, вы можете скопировать / вставить ее в скрипт, чтобы создать разумный синтаксический анализатор командной строки. Это определенно не то, что я бы запомнил, но использование лямбда-арности в качестве дешевого парсера - новая идея:
источник
Я собираюсь поделиться своим собственным простым анализатором параметров, над которым я работал некоторое время. Это всего лишь 74 строки кода, и он выполняет основы того, что делает внутренний синтаксический анализатор параметров Git. Я взял за основу OptionParser, а также Git.
https://gist.github.com/felipec/6772110
Выглядит это так:
источник
EasyOptions вообще не требует кода синтаксического анализа параметров. Просто напишите текст справки, требуется, готово.
источник