EDIT: Proszę, proszę , proszę zapoznać się z wymaganiami dwa wymienione na dole tego postu, zanim odpowiedział. Ludzie wciąż publikują swoje nowe perełki, biblioteki i tak dalej, co najwyraźniej nie spełnia wymagań.
Czasami chcę bardzo tanio zhakować niektóre opcje wiersza poleceń do prostego skryptu. Zabawnym sposobem na zrobienie tego bez zajmowania się getopts, parsowaniem lub czymkolwiek w tym stylu jest:
...
$quiet = ARGV.delete('-d')
$interactive = ARGV.delete('-i')
...
# Deal with ARGV as usual here, maybe using ARGF or whatever.
Nie jest to do końca normalna składnia opcji Unixa, ponieważ akceptuje opcje nie będące opcjami parametry wiersza poleceń, jak w " myprog -i foo bar -q
", ale mogę z tym żyć. (Niektórzy ludzie, na przykład programiści Subversion, wolą to. Czasami ja też.)
Opcji, która jest po prostu obecna lub nieobecna, nie można zaimplementować w prostszy sposób niż powyższe. (Jedno przypisanie, jedno wywołanie funkcji, jeden efekt uboczny). Czy istnieje równie prosty sposób radzenia sobie z opcjami, które pobierają parametr, na przykład „ -f
nazwa pliku ”?
EDYTOWAĆ:
Jedna uwaga, której nie powiedziałem wcześniej, ponieważ nie stało się dla mnie jasne, dopóki autor Trollop nie wspomniał, że biblioteka mieści się „w jednym [800-wierszowym] pliku”, jest to, że szukam nie tylko czystego składnia, ale dla techniki, która ma następujące cechy:
Cały kod można zawrzeć w pliku skryptu (bez przytłaczania samego skryptu, który może mieć tylko kilkadziesiąt linii), dzięki czemu można upuścić pojedynczy plik w katalogu
bin
na dowolnym systemie ze standardowym Ruby 1.8 , [5-7] instalacji i używaj go. Jeśli nie możesz napisać skryptu Rubiego, który nie zawiera instrukcji wymagających, a kod do parsowania kilku opcji ma mniej niż kilkanaście wierszy, nie spełnisz tego wymagania.Kod jest mały i na tyle prosty, że można go zapamiętać na tyle, aby bezpośrednio wpisać kod, który załatwi sprawę, zamiast wycinać i wklejać z innego miejsca. Pomyśl o sytuacji, w której jesteś na konsoli serwera z zaporą ogniową bez dostępu do Internetu i chcesz wrzucić razem szybki skrypt do użycia przez klienta. Nie wiem jak Ty, ale (poza niespełnieniem powyższego wymagania) zapamiętywanie nawet 45 linijek uproszczonej mikroopcji nie jest czymś, na czym mi zależy.
getoptlong
ioptparse
są w standardowej bibliotece Ruby, więc nie ma potrzeby kopiowania ich podczas wdrażania skryptu - jeżeli rubin działa na tej maszynie, torequire 'optparse'
czyrequire 'getoptlong'
będzie działać zbyt.Odpowiedzi:
Jako autor Trollop , nie mogę WIERZYĆ rzeczy, które ludzie uważają za rozsądne w parserze opcji. Poważnie. To zdumiewa umysł.
Dlaczego powinienem tworzyć moduł, który rozszerza inny moduł, aby analizować opcje? Dlaczego powinienem cokolwiek tworzyć podklasy? Dlaczego miałbym subskrybować jakiś „framework” tylko po to, aby przeanalizować wiersz poleceń?
Oto wersja powyższego Trollopa:
I to wszystko.
opts
obecnie jest hash z kluczami:quiet
,:interactive
i:filename
. Możesz z nim zrobić, co chcesz. Otrzymujesz piękną stronę pomocy, sformatowaną tak, aby pasowała do szerokości ekranu, automatyczne krótkie nazwy argumentów, sprawdzanie typów ... wszystko, czego potrzebujesz.To jeden plik, więc możesz go upuścić w swoim katalogu lib /, jeśli nie chcesz formalnej zależności. Ma minimalne DSL, które można łatwo odebrać.
LOC na opcję osób. To ma znaczenie.
źródło
Podzielam wasz odrazę do
require 'getopts'
, głównie z powodu niesamowitości, jaką jestOptionParser
:źródło
Oto standardowa technika, której zwykle używam:
źródło
lib
folderze lub kodzie i używać go bez dotykania rubygemów.when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
nawhen /^-/ then usage("Unknown option: #{ARGV.shift.inspect}")
lub wpadłby w nieskończoną pętlę użytkowaniaPonieważ nikt nie pojawił się, żeby go wymienić, a tytuł ma odnosić się do taniego wiersza polecenia parsowania, dlaczego po prostu nie pozwól Ruby tłumacza pracować dla Ciebie? Jeśli przejdziesz
-s
przełącznik (na przykład w swoim shebang), otrzymasz za darmo proste przełączniki, przypisane do jednoliterowych zmiennych globalnych. Oto przykład użycia tego przełącznika:A oto wynik, kiedy zapiszę to jako
./test
i chmod+x
:Zobacz
ruby -h
szczegóły.To musi być tak tanie, jak to tylko możliwe. Spowoduje to zgłoszenie błędu NameError, jeśli spróbujesz przełączyć się
-:
, więc jest tam pewna walidacja. Oczywiście nie możesz mieć żadnych przełączników po argumencie bez przełączania, ale jeśli potrzebujesz czegoś wymyślnego, naprawdę powinieneś używać co najmniej OptionParser. Właściwie jedyną rzeczą, która mnie denerwuje w tej technice, jest to, że otrzymasz ostrzeżenie (jeśli je włączyłeś) podczas uzyskiwania dostępu do nieustawionej zmiennej globalnej, ale nadal jest to błąd, więc działa dobrze w przypadku narzędzi jednorazowych i szybkich skrypty.Jedynym zastrzeżeniem, na które zwrócił uwagę FelipeC w komentarzach w " Jak zrobić naprawdę tanią analizę opcji wiersza poleceń w Rubim ", jest to, że twoja powłoka może nie obsługiwać 3-znakowego shebang; może zajść potrzeba zastąpienia
/usr/bin/env ruby -w
rzeczywistą ścieżką do twojego ruby (np./usr/local/bin/ruby -w
), uruchomienia go ze skryptu opakowującego lub czegoś podobnego.źródło
Zbudowałem mikro-optparse, aby wypełnić tę oczywistą potrzebę krótkiego, ale łatwego w użyciu parsera opcji. Ma składnię podobną do Trollopa i jest krótka o 70 linii. Jeśli nie potrzebujesz walidacji i możesz obejść się bez pustych wierszy, możesz zmniejszyć liczbę do 45 wierszy. Myślę, że właśnie tego szukałeś.
Krótki przykład:
Wywołanie skryptu za pomocą
-h
lub--help
spowoduje wydrukowanieSprawdza, czy dane wejściowe są tego samego typu, co wartość domyślna, generuje krótkie i długie metody dostępu, wyświetla opisowe komunikaty o błędach w przypadku podania nieprawidłowych argumentów i nie tylko.
I w porównaniu kilka Option parser za pomocą każdego Option parser do problemu miałem. Możesz skorzystać z tych przykładów i mojego podsumowania, aby podjąć pouczającą decyzję. Zapraszam do dodawania kolejnych realizacji do listy. :)
źródło
optparse
1937 liniach i wymagasz od nich (dajesz lub bierzesz).optparse
jest to biblioteka domyślna, tj. Jest dostarczana z każdą instalacją Rubiego.Trollop
jest biblioteką innej firmy, dlatego za każdym razem, gdy chcesz dołączyć go do projektu, musisz zaimportować cały kod. µ-optparse zawsze wymaga tylko ~ 70 linii, ponieważoptparse
już tam są.Całkowicie rozumiem, dlaczego chcesz uniknąć optparse - może to być za dużo. Ale jest kilka znacznie „lżejszych” rozwiązań (w porównaniu do OptParse), które są dostępne jako biblioteki, ale są na tyle proste, że opłacalna jest pojedyncza instalacja klejnotów.
Na przykład sprawdź ten przykład OptiFlag . Tylko kilka wierszy do przetworzenia. Nieco skrócony przykład dostosowany do Twojego przypadku:
Istnieje również mnóstwo niestandardowych przykładów . Pamiętam, że korzystałem z innego, który był jeszcze łatwiejszy, ale na razie mi to umknęło, ale wrócę i dodam tutaj komentarz, jeśli go znajdę.
źródło
Oto, czego używam do naprawdę, naprawdę tanich argumentów:
więc jeśli uruchomisz
programname foo bar
, wywoła foo, a następnie bar. Jest to przydatne w przypadku jednorazowych skryptów.źródło
Możesz spróbować czegoś takiego:
źródło
Czy rozważałeś Thor by wycats? Myślę, że jest o wiele czystszy niż optparse. Jeśli masz już napisany skrypt, sformatowanie go lub refaktoryzacja dla thora może wymagać trochę więcej pracy, ale sprawia, że obsługa opcji jest bardzo prosta.
Oto przykładowy fragment z pliku README:
Thor automatycznie mapuje polecenia takie jak:
To zostanie przekonwertowane na:
źródło
--help
wyników? A co jeśli "head myprogram.rb" był wyjściem pomocy?Oto mój ulubiony parser opcji szybkiego i łatwego:
Opcje są wyrażeniami regularnymi, więc „-h” również pasowałoby do „--help”.
Czytelny, łatwy do zapamiętania, brak zewnętrznej biblioteki i minimalny kod.
źródło
/-h(\b|elp)
Trollop jest dość tani.
źródło
Jeśli potrzebujesz prostego parsera wiersza poleceń dla poleceń klucz / wartość bez użycia klejnotów:
Ale to działa tylko wtedy, gdy zawsze masz pary klucz / wartość.
Jeśli nie potrzebujesz sprawdzania, możesz po prostu użyć:
źródło
Oto fragment kodu, którego używam u góry większości moich skryptów:
Nienawidzę również wymagać dodatkowych plików w moich szybkich skryptach. Moje rozwiązanie jest prawie tym, o co prosisz. Wklejam 10-wierszowy fragment kodu na górze dowolnego z moich skryptów, który analizuje wiersz poleceń i umieszcza argumenty pozycyjne i przełącza się w obiekt Hash (zwykle przypisany do obiektu, który nazwałem arghash w poniższych przykładach).
Oto przykładowy wiersz poleceń, który możesz chcieć przeanalizować ...
Który stałby się takim hasłem.
Oprócz tego do skrótu dodano dwie wygodne metody:
argc()
zwróci liczbę argumentów bez przełączania.switches()
zwróci tablicę zawierającą klucze dla obecnych przełącznikówOznacza to pozwolenie na szybkie i brudne rzeczy, takie jak ...
arghash.argc == 2
)arghash[1]
Zawsze pobiera drugi argument nie przełączający).arghash['--max=']
co daje wartość „15”, biorąc pod uwagę przykładowy wiersz poleceń.arghash['-s']
wartość true, jeśli jest obecny i zero, jeśli jej nie ma.Sprawdź obecność przełącznika lub alternatywnych przełączników za pomocą operacji na zestawach, takich jak
puts USAGETEXT if !(%w(-h --help) & arghash.switches()).empty?
Zidentyfikuj użycie nieprawidłowych przełączników za pomocą operacji na zestawach, takich jak
puts "Invalid switch found!" if !(arghash.switches - %w(-valid1 -valid2)).empty?
Określ wartości domyślne dla brakujących argumentów, używając prostego
Hash.merge()
przykładu, takiego jak poniższy przykład, który wypełnia wartość -max =, jeśli nie została ustawiona, i dodaje czwarty argument pozycyjny, jeśli nie został przekazany.with_defaults = {'-max=' => 20, 3 => 'default.txt'}.merge(arghash)
źródło
=
) może mieć wpływ na potrzebny kod.Jest to bardzo podobne do zaakceptowanej odpowiedzi, ale używając
ARGV.delete_if
tego, czego używam w moim prostym parserze . Jedyną prawdziwą różnicą jest to, że opcje z argumentami muszą być razem (np-l=file
.).źródło
Najwyraźniej @WilliamMorgan i myślę podobnie. Właśnie opublikowałem wczoraj wieczorem na Github, co teraz widzę, jest podobną biblioteką do Trollop (Nazwana jak?) Po wyszukaniu OptionParser na Github, zobacz Przełączniki
Jest kilka różnic, ale filozofia jest taka sama. Jedną oczywistą różnicą jest to, że przełączniki są zależne od OptionParser.
źródło
Rozwijam się własny klejnot parsera opcji o nazwie Acclaim .
Napisałem go, ponieważ chciałem stworzyć interfejsy wiersza poleceń w stylu git i móc wyraźnie oddzielić funkcjonalność każdego polecenia na osobne klasy, ale można go również używać bez całej struktury poleceń:
Na razie brak stabilnej wersji, ale zaimplementowałem już kilka funkcji, takich jak:
Duży nacisk kładzie się na polecenia, więc może to być trochę trudne do prostego analizowania wiersza poleceń, ale działa dobrze i używam go we wszystkich moich projektach. Jeśli interesuje Cię aspekt interfejsu poleceń, sprawdź stronę projektu GitHub, aby uzyskać więcej informacji i przykładów.
źródło
Załóżmy, że polecenie ma co najwyżej jedną akcję i dowolną liczbę opcji, takich jak ta:
Parsowanie bez walidacji może wyglądać następująco:
źródło
https://github.com/soveran/clap
46LOC (w wersji 1.0.0), brak zależności od zewnętrznego parsera opcji. Wykonuje zadanie. Prawdopodobnie nie jest tak w pełni funkcjonalny jak inne, ale jest to 46LOC.
Jeśli sprawdzisz kod, możesz dość łatwo zduplikować podstawową technikę - przypisz lambdy i użyj arity, aby upewnić się, że odpowiednia liczba argumentów podąża za flagą, jeśli naprawdę nie chcesz mieć zewnętrznej biblioteki.
Prosty. Tani.
EDYCJA : podstawowa koncepcja sprowadziła się do końca, ponieważ przypuszczam, że można skopiować / wkleić go do skryptu, aby stworzyć rozsądny parser wiersza poleceń. Na pewno nie jest to coś, co chciałbym zapamiętać, ale użycie arności lambda jako taniego parsera to nowatorski pomysł:
źródło
Zamierzam udostępnić własny prosty parser opcji, nad którym pracuję od jakiegoś czasu. To zaledwie 74 wiersze kodu i zawiera podstawy tego, co robi wewnętrzny parser opcji Gita. Jako inspirację wziąłem OptionParser, a także Git.
https://gist.github.com/felipec/6772110
To wygląda tak:
źródło
EasyOptions w ogóle nie wymaga żadnego kodu analizującego opcje. Po prostu napisz tekst pomocy, wymagaj, gotowe.
źródło