コマンドラむンアプリケヌションの構築CLI

この蚘事は、David CopelandのRubyでのすばらしいコマンドラむンアプリケヌションの構築 賌入 、 ダりンロヌド、 詳现 の圱響を受けお曞かれたした。 そのほずんどは、䜿甚する蚀語に関係なく、CLIアプリケヌションの蚭蚈の蚭蚈に専念したす。 このプロセスでは、ルビヌに固有の事項に぀いお説明したすが、それを知らなくおも怖くはありたせん。コヌドが倚すぎるこずはありたせん。 この蚘事は、自身の経隓が散りばめられた前述の本のかなり詳现なレビュヌず考えるこずができたす。 私は本を​​お勧めしたす

たず、質問をしたす。 IT-shnikovのコミュニティを芋るず、矎しいグラフィカルむンタヌフェむスを備えたプログラムが豊富にあるにもかかわらず、コマンドラむンアプリケヌションが非垞に人気があるこずがわかりたす。 なんで
いく぀かの答えがありたす。 たず、 非垞に䟿利です。コマンドラむンでコマンドを䜿甚しおタスクを蚘述できれば、マりスの動きを分析しおさたざたなメニュヌ項目をクリックする必芁がある堎合よりも自動化がはるかに簡単になりたす。 第二に、信じられないほど倚くの方法でプログラムを組み合わせるこずが可胜になりたす。これは、グラフィカルむンタヌフェむスを䜿甚しお達成するこずは困難です。
Unixの哲孊は、倚くの堎合、それぞれ独自の特定のタスクを実行できる倚くの小さなナヌティリティが、1぀の倚機胜ナニバヌサルプログラムよりも優れおいるずいう原則に基づいおいたす。 そしお、これは、IT-shnikovの䞖界でUnixシステムが成功した理由の1぀です。
おそらく、誰もがGUIからCLIに普通のナヌザヌを匕き付けるこずができるずは考えにくいこずを理解しおおり、「コンピュヌタヌサむ゚ンティスト」ずいう私たちに焊点を合わせお、CLIアプリケヌションに察する垌望を明確にしたしょう。

䞀般的な芁件


簡単に蚀えば、それらを単玔に、しかし効率的に䜿甚したいのです。 David Copelandは、これを達成するためのアプリケヌション芁件の包括的なリストを䜜成したした。

次に、これらのポむントに぀いおさらに詳しく説明したす。

䜿いやすい


ナヌティリティず゜フトりェアパッケヌゞ。 どちらが䟿利ですか

そのため、すべおのアプリケヌションは、ナヌティリティず゜フトりェアパッケヌゞ元のコマンドスむヌトの2぀のタむプに条件付きで分割できたす。

最初のタむプは、1぀の目暙ず1぀の操䜜モヌドを持぀アプリケヌションです。 このタむプのプログラムには数え切れないほどの䟋があり、ほずんどすべおのUnixコマンドは次のずおりですls、grep、diff、... さらに、連続凊理のためにチェヌンに接着するのが簡単です。 ここでは、次の䟋えが関係したす。 あなたが家を建おおいるず想像しおください。さらに、その家は暙準モデルではありたせん。 モノリシックブロックからではなく、レンガから構築する方がはるかに䟿利です。堎所によっおはこれらのブロックをファむルする必芁があり、どこかで石でゞョむントを閉じる必芁があるためです。 はい、ブロックはクレヌンでしか匕っ匵るこずができたせんが、レンガは手で眮くこずができたす。

2番目のタむプのプログラムは、スむスのナむフたたはフヌドプロセッサヌず比范できたす。 時には非垞に䟿利です。 gitを芋おくださいruby、gem、rails、bundleの䞖界ではすぐに蚘憶されたす-1぀のプログラムですが、それをいく぀実行できたすか。 そしお、圌女はコミット/チェックアりトでき、自分で履歎を怜玢し、ファむル間の倉曎を怜蚎したす。 そのため、grep、diffなどが組み蟌たれおいたす。Gitに䜕も組み合わせる必芁はありたせん。圌はすべおを行う方法を知っおいたす。 家ずの類掚に戻るず、gitaにはあらゆる堎面で暙準的なプロゞェクトがありたすそしお、それらすべおを思い出そうずしたす。
それでも、すべおのプログラムが倚機胜である必芁はありたせん。すべお同じように、すべおのナヌスケヌスを実行するわけではありたせん。 この論文をサポヌトするために、cd、ls、pwd、diff、df、および䟿利な操䜜を1぀のコマンドで実行できる「マルチツヌル」を想像するこずをお勧めしたす。オプションを少し倉曎するだけですたずえば、ファむルシステムの倉曎、ファむルシステムの衚瀺、  䜿いたすか 私はあなたが過床のかさばりのために捚おるず思いたす。 ゜フトりェアパッケヌゞは非垞に䟿利ですが、8぀の觊手でケンタりロスを曞く前に慎重に考えるこずは理にかなっおいたす。

ずころで、倚数のナヌティリティを䜜成し、それを゜フトりェアパッケヌゞにしたい堎合は、修正するのはそれほど難しくありたせん。 コマンドをルヌティングするラッパヌを䜜成するだけです。 知らないかもしれたせんが、gitはコマンドの皮類に基づいおgitコマンドが制埡を転送するgit-commit、git-show、git-hash-object、git-cat-file、git-update-indexなどの倚数のナヌティリティで構成されおいたすオプションもちろん、ナヌティリティ呌び出しの単䞀チェヌンが1぀のコマンドの背埌にある堎合がありたす。 そのため、将来結合する小さなプログラムのセットで倧芏暡なプロゞェクトを開始するこずをお勧めしたす。 䜜成、デバッグ、保守、䜿甚が簡単です。

コマンドラむン匕数の構文たたは「この家には独自の䌝統がありたす。」

甚語から始めたす。 コマンドラむンアプリケヌションを起動するずきに、いく぀かのパラメヌタヌセットを指定したす。 それらは次のタむプに分けられたすオプションず匕数。 David Copelandは、オプションをさらに2぀のサブタむプフラグずスむッチに分割したす。
抂略的には、次のexecutable [options] <arguments>ずしおこれを衚すこずができexecutable [options] <arguments> 。 すべおが最新であるず思いたすが、念のため、角括匧内のパラメヌタはオプションであり、山括匧内のパラメヌタは必須であるこずを説明したす。

匕数たたは䜍眮匕数は、プログラムが機胜するために指定する必芁があるパラメヌタヌです。 それらの順序は厳密に定矩されおいたす。
オプションはオプションのパラメヌタヌです。 それらは任意の順序で指定できたす。
スむッチタむプオプションはブヌルオプションであり、プログラムはその有無をチェックしたす。 䟋-- --ignore-case たたは、 --ignore-case --no-ignore-case 。
フラグタむプオプションは、パラメヌタ付きのオプションです。 このパラメヌタヌにはデフォルト倀がありたす。 たずえば、私のバヌゞョンではgrep -C ...ずgrep -C 2 ...堎合、grepナヌティリティは同等です。
匕数ずオプションの䞡方にデフォルト倀がある堎合がありたすが、そうでない堎合がありたす。

䟋ずしお、 grep --ignore-case -r - 4 "some string" /tmp匕数は"some string" /tmpであり、オプションは--ignore-case -r - 4です。 同時に、 --ignore-caseず-rはスむッチであり、 -C 4はフラグです。

オプションの芏則

オプションは、短い-i圢匏ず長い--ignore-case圢匏の䞡方で指定できたす。 原則ずしお、スクリプトのコマンドラむンオプションを盎接キャプチャできるため、オプション圢匏を奜きなように楜しむこずを劚げるものは䜕もありたせん。 しかし、Unixコミュニティによっお開発されたルヌルを順守するこずをお勧めしたす。ルヌルは時を経お研ぎ柄たされ、ほずんどの人がそれに慣れおいたす。 さらに、これらのオプションを簡単に操䜜できる既補のラむブラリがありたす。
これらのルヌルは次のずおりです。


長い遞択肢があるこずが垞に掚奚される理由

通垞、オプションの長い圢匏は、アプリケヌションを䜿甚しおスクリプトを蚘述する際に䜿甚されたす。 長いオプションは自己文曞化する必芁がありたす。 sysadminがcronを調べお、理解できないオプション-zsf -m 100れるデヌタベヌスバックアップタスクの起動を確認したずしたす。 圌がスクリプトの䜜成者でない堎合は、䜕を意味するのかを理解するために、圌は助けに朜り蟌む必芁がありたす。 同意しお、オプションのセット--scheme --max-size 100 --gzip --forceは圌にもっず倚くを䌝え、時間を無駄にしないようにしたす。
さらに、めったに䜿甚されないオプションの短いオプションを䜜成するこずは掚奚されたせん。 たず、アルファベットのすべおの行のオプションにそれらを費やすほど倚くの文字がありたせん。 第二に、さらに重芁なこずは、短いオプションがないこずで、このオプションは通垞の操䜜では二次的たたは望たしくないこずであり、単玔にできるからずいっお軜率に䜿甚しないでください。
そのため、頻繁に䜿甚されるオプションは短いものず長いものの䞡方であり、めったに䜿甚されないオプションは長いだけです。

単機胜アプリケヌションず倚機胜アプリケヌションのコマンドラむンオプションの違い

これらの2぀のタむプのアプリケヌションは、呌び出されたずきに匕数の順序がわずかに異なりたす。
最初のタむプのアプリケヌションの堎合、呌び出しは通垞次のようになりたす。 executable [options] <arguments>
゜フトりェアパッケヌゞの堎合、圢匏はやや耇雑です。 executable [global options] <command> [command options] <arguments>
この本の䟋を次に瀺したすgit --no-pager push -v origin_master --no-pagerは、任意のgitコマンドに適甚できるオプションです。 --no-pager git --no-pager push -v origin_masterは、pushコマンドに固有のオプションです。 グロヌバルオプションずコマンド固有のオプションは同じ名前を持぀こずができるこずに泚意しおください。 ただし、この堎合、すべおのツヌルがそれらの凊理に適しおいるわけではありたせん。たずえば、暙準のOptionParser ruby​​ラむブラリは、オプションが満たされた堎所を区別しないため、このタスクに察凊したせん。 ゜フトりェアパッケヌゞを䜜成する堎合は、GLIラむブラリをより適切に䜿甚しおください。

念のため、入力プログラムは技術的にはパラメヌタヌの文字列ではなく、既に芁玠に分割されたパラメヌタヌの配列を受け取っおいるこずを読者に思い出させたす。 ルビヌでは、この配列はARGVず呌ばれたす。 私たちが盎接たたは特別な図曞通の助けを借りお働くのは圌ず䞀緒です。 スペヌスで芁玠に分割されおいないこずに泚意しおくださいそうでない堎合、たずえば、スペヌスを含むファむル名にするこずはできたせん、シェルのルヌルはやや耇雑です。 たた、文字の゚スケヌプずグルヌプ化のための匕甚笊の䜿甚も含たれたす。 パラメヌタ文字列をスクリヌニング、接着、たたは配列にカットする必芁がある堎合、たたはその逆の堎合-暙準シェルワヌドラむブラリをご芧ください。 これらの目的のために、 String#shellescape 、 String#shellescape 、 Array#shelljoinの3぀のメ゜ッドのみで構成されおいたす。

rubyコミュニティでは、ほずんどのコマンドラむンアプリケヌションはOptionParserたたはそれに基づくラむブラリを䜿甚したす。 構成に関するセクションで-もう少し孊習したら、OptionParserを䜿甚しお䜜成したコヌドの䟋を瀺したす。

圹に立぀


䜿甚するawesome_programプログラムを初めお芋たずきを想像しおください。 経隓豊富なナヌザヌずしおは、恐らくawesome_program --helpしお、匕数の順序、䞀連のオプション、および䜿甚䟋を確認するこずを期埅したす。 プログラムをリリヌスするずき、最初に芋たナヌザヌがおそらく最初に同じこずをするこずを芚えおおいおください。したがっお、 -h 、-- --helpオプションを甚意しおおいおください。 タむプOptionParserのラむブラリを䜿甚する堎合、プログラムが指定した説明ずずもに認識するすべおのオプションのリストが、プロンプト行に自動的に远加されたす。

ヘルプ行に加えお、拡匵ヘルプを人で曞くこずは理にかなっおいたす。 ただし、私の知る限り、rubygemsはmanでペヌゞを自動的に蚭定したせん。 ただし、システムにむンストヌルされたgemのマニュアルドキュメントペヌゞを衚瀺できるgem-man gemがありたす。
マニュアルを䜜成するには、難しいnroff圢匏のファむルを䜜成する必芁がありたす。 タスクを簡玠化するには、ronnコンバヌタヌラむブラリを䜿甚したす。これにより、ドキュメントペヌゞをより単玔な圢匏で䜜成できたす。 すべおの準備ができたら、 gem man awesome_gem䜿甚しお、ヘルプ行を確認できたす。 たたは、 alias gem='gem man -s'蚘述できたす。 この堎合、manコマンドはgem manコマンドに眮き換えられ、gemのヘルプを探すこずができたす。 gem-manが凊理できなかったリク゚ストに察しお、通垞のmanの察応するペヌゞぞの自動リダむレクトが発生したす。
あなた自身のマンチップを䜜るこずを蚈画しおいるなら、本を芋おください、これにより倚くの泚意が払われたす。

ナヌザヌがコマンドを実行しやすくするために、シェルレベルでチヌムを自動補完するこずができたすすべおのシェルで機胜するわけではありたせん。 これにより、タブボタンを抌しお、コマンド名、ファむル名などを自動的に補完できたす。 ナヌザヌはスペルミスをする可胜性が䜎くなり、コマンドを曞く時間を倧幅に短瞮できたす。

タブ補完を行い、プログラム内のコマンドの履歎を保存するにはirbなどのプログラムの察話モヌドで、rubyに組み蟌たれたreadlineラむブラリを䜿甚するだけで十分です。 gets代わりにReadline.readlineコマンドを䜿甚しお、入力したすべおのコマンドの履歎を自動的に保存できたす。

タブ補完は次のように行われたす。 Readline.completion_proc=(block)がReadline.completion_proc=(block)メ゜ッドに返されたす。このメ゜ッドは、既に入力されたテキストの行に远加可胜な配列を返したす。これがタスク党䜓です。 䟋
 Readline.completion_proc = proc { |input| allowed_commands.grep /^#{input}/ } 


すでに実行䞭のプログラムのレベルではなく、シェルのレベルでタブ補完が必芁な堎合、これはやや耇雑です。 .bashrcをいじる必芁があり.bashrc 。
最初に、行complete -F get_my_app_completions my_app远加complete -F get_my_app_completions my_app
これで、 my_app()[- ]を入力しおからmy_app()[- ]を入力するmy_app()[- ]に、 get_my_app_completions関数が呌び出されたす。 この関数は、可胜な自動補完オプションをCOMPREPLY倉数にCOMPREPLYたす。この倉数は、シェルがナヌザヌに远加オプションを提䟛するために䜿甚したす。 .bashrcこの関数を定矩する必芁がありたす。 todoアプリケヌションの本から䟋を瀺したす。
 function get_todo_completions() { if [ -z $2 ] ; then #    COMPREPLY=(`todo help -c`) else #      ,   $2 COMPREPLY=(`todo help -c $2`) fi } complete -F get_todo_completions todo 

ここで、プログラムで次の動䜜を実装する必芁がありたすこれは簡単な挔習ずしお残したしょう。
1コマンドラむンでtodo help -cを手動で入力するず、アプリケヌションコマンドのリストが衚瀺されたすlist、add、complete、helpそれぞれ独自の行にありたす
2 todo help -c complete 、開始されたがただ完了しおいないすべおのタスクのリストが衚瀺されたす完党なコマンドを適甚できるタスク。

help -c [...]はサヌビスコマンドです。その存圚は簡単なヘルプで省略できたす。 ナヌザヌが䜿甚するのではなく、 .bashrcスクリプトを䜿甚するこずを前提ずしおい.bashrc 。
このスクリプトでは、関数は既に入力されおいるものに基づいお、䜕を眮換できるかをアプリケヌション自䜓に尋ねたすこれはhelp -オプションの埌に枡されたす。 プログラムは、アプリケヌションにこのような特別なパラメヌタヌセットが䞎えられたずきの状況を監芖し、暙準出力にすべおのオプションのリストを衚瀺したす既に芋たように、そこから盎接シェルスクリプトCOMPREPLY送信されCOMPREPLY 。
この本の著者は、独自のGLIラむブラリを䜿甚しおいたす。GLIラむブラリは、このようなオプションセットを自動的に远跡したす。 GLIの助けを借りずに、この機胜を簡単に実装できたす。 ご芧のずおり、ここには魔法はありたせん。

他の人ずうたく遊ぶ


プログラム間の䟿利な盞互䜜甚の必芁性の問題に぀いおは議論したせん。Unixで働いた誰もがこれがどれほど重芁かを評䟡できたす。 䞻な問題は、これを達成する方法です。

リタヌンコヌド

たず、リタヌンコヌドを䜿甚したす。 プログラムが正垞に完了した堎合-0、゚ラヌが発生した堎合-れロ以倖のさたざたなリタヌンコヌド。 シェルスクリプトは、最埌に完了したプログラムのステヌタスを$?倉数から芁求するこずにより、プログラムが正垞に動䜜したかどうかを刀断できるため、これは重芁$? 。 戻りステヌタスを返すために、rubyはexit(exit_status)メ゜ッドを䜿甚したす。
さたざたな゚ラヌにさたざたなリタヌンコヌドを割り圓おるず、自分のプログラムを䜿甚する別のプログラムが問題を修正できるかどうか、および泚意を払う䟡倀があるかどうかを刀断できる可胜性がありたす。 プログラムの倖では、プログラムが「クラッシュ」したかどうかが怖いかどうかを確認する方が良いでしょう。 異なるリタヌンコヌドは異なる䟋倖クラスのようなものです。RAMがないずいう事実に゚ラヌがあるか、ネットワヌクが䞀瞬消えただけで再詊行する䟡倀がありたす。 䞀郚のプログラムは、いく぀かの゚ラヌにより同時にクラッシュする堎合がありたす。 䞀床に耇数の問題を報告する必芁がある堎合は、ビットマスクを䜿甚したす。 ネットワヌクには、どの゚ラヌに察しおどのリタヌンコヌドを䜿甚するのが䞀般的かに぀いおの掚奚事項がありたす。GNU 非垞に䞀般的なおよびFreeBSD 非垞に具䜓的なサむトでそれに぀いお読むこずができたす。 ゚ラヌコヌドを気にしたくない堎合は、少なくずも最小限の努力をしおください-゚ラヌが発生した堎合、少なくずもいく぀かのれロ以倖の倀を返したす。 そうしないず、他のプログラムはあなたのプログラムが正垞に動䜜したかどうかを知るこずさえできたせん。

ずころで、シェルスクリプトからだけでなく、rubyスクリプトからもプログラムを実行できたす。 これを行うには、 Kernel.systemやIO.popenなど、いく぀かのオプションがありたすIO.popen詳现に぀いおは、ドキュメントをご芧ください。 systemを䜿甚しお別のプログラムを呌び出す堎合、同様のシェル倉数$?でその戻りコヌドを芋぀けるこずができたす$? 。

I / Oストリヌムず゚ラヌストリヌム。 パむプ

コマンドラむンから起動されるプログラムの盞互䜜甚の䞻な方法はパむプです。 パむプは、あるプログラムの出力を別のプログラムの入力にリダむレクトする方法です。 瞊棒でマヌクされたパむプ| 。 たずえば、 ls | sort ls | sort 、最初の郚分-lsは画面に䜕も衚瀺したせんが、代わりにその出力をsortプログラムの入力にリダむレクトしたす。 たた、゜ヌトプログラムは入力ストリヌムからテキストを1行ず぀取埗し、すでに゜ヌトされたリストが画面に衚瀺されたす。 䞀方では、ls自䜓がファむルを゜ヌトできたすが、これは意図されおいたせん。 同時に、゜ヌトはこの目的のためだけに必芁であり、倚くのオプションがありたす。 たずえば、名前が数字で始たる堎合は、蟞曞匏ではなく行を䞊べ替えるこずができたすそうでない堎合、順序は1.jpg、10.jpg、100.jpg、2.jpg、...のようになりたす。 たたは、逆の順序で䞊べ替えたす。 さらに、特別なプログラムawk、sedなどを䜿甚しお、文字列を䞊べ替える前に、それを修正できたすたずえば、プレフィックスを消去したす。 パむプは任意の数のプログラムで構成できるこずに泚意しおください。 だからls | sort -n | tail ls | sort -n | tail ls | sort -n | tailは、番号順に゜ヌトされたファむルのリストの最埌の10行を衚瀺したす。

プログラムで入出力ストリヌムが必芁になる理由を考えおください。 出力ストリヌムに曞き蟌む内容、および゚ラヌストリヌムに曞き蟌む内容。 最初に2番目の質問を扱いたす。出力ストリヌムstdoutず゚ラヌstderrの違いは䜕ですか 1぀のスレッドがパむプに接続し、もう1぀のスレッドが接続しないずいう事実。 stderrストリヌムは、゚ラヌの出力だけでなく、プログラム実行の段階、デバッグ情報など、ワヌクプロセスに関する情報の出力にも䜿甚されたす。 この情報は、別のプログラムの入力に枡されるべきではなく、ナヌザヌの䟿宜のためにのみ必芁です。 stdoutストリヌムは、プログラムの結果など、他のすべおの情報に䜿甚されたす。

人だけでなく、マシンもプログラムの出力を凊理する必芁があるため、出力圢匏に぀いお考える必芁がありたす。 オプション--format=<plain|csv|pretty|html|table|...>を䜜成するのは理にかなっおいたす。 人間が読める圢匏pretty / html / tableを指定する堎合、出力の解析の利䟿性を考慮せずに、目を楜にする方法で情報を衚瀺できたす。 機械可読圢匏plain / csvを指定する堎合、結果が矎しく芋えるかどうかは関係ありたせん-䞻なこずは、解析を容易にするこずです。 構文解析の利䟿性のために、タブ区切り倀たたはコンマ区切り倀csvを䜿甚するか、圢匏は1行-倀、たたは最適な別の圢匏です。 たた、Delight Usersセクションで、できる限り快適な結論を出す方法に぀いおも説明したす。
ナヌザヌは、プログラムを起動するたびに出力圢匏を指定したくないため、すべおの堎合に遞択するこずも垞に可胜ずは限りたせん。 出力が人の目か機械の目かを自動的に刀断するトリック、぀たりIO#tty?メ゜ッドはありIO#tty? 。 $stdout.tty? 出力が端末に向けられおいるかどうかを教えおくれたす。 そうでない堎合、プログラムの出力はパむプにls > output.txtれるか、ファむルにリダむレクトされたす次のように ls > output.txt 。 端末ぞの出力ずリダむレクトされたストリヌムぞの出力では、異なるデフォルトのフォヌマットoptions[:format] = $stderr.tty? ? 'table' : 'csv'遞択できたすoptions[:format] = $stderr.tty? ? 'table' : 'csv' options[:format] = $stderr.tty? ? 'table' : 'csv'
たた、たずえば、人向けの出力圢匏でファむルに結果を出力する堎合は、圢匏を明瀺的に指定するだけです。

次に、入力ストリヌムに぀いお説明したす。 プログラムは入力ストリヌムからどのようなデヌタを受け入れるべきですか もちろん、これはプログラムの詳现に䟝存したす。 考えおみたしょう、どのデヌタを入力ストリヌムに入れるこずができたすか 明らかな答えは、他のプログラムが出力に持っおいるものです。 たずえば、マトリックスファむルを別の圢匏に倉換し、別の拡匵子を持぀ファむルに曞き蟌むプログラムがありたす。 入力ストリヌムから行列を受け入れるこずは理にかなっおいたすか 私の意芋では、そうではありたせん。この行列がどのように、そしおなぜ入力ストリヌムに入るのでしょうか 䞀床に倚くのファむルを凊理するために、倚数のファむル名を受け入れる方がはるかに䟿利です。 これは、たずえばlsコマンドが提䟛できるデヌタです。
, , . -, . , , , (, — — Windows-). , , . , .
, , $stdin.tty?


, , ( ) — . , , -, , . ( SIGHUP), , , , . SIGINT, Ctrl+C. Signal.trap . , , . ( , ) POSIX-, .. Unix, Windows. , , Windows , Unix, - , — , .
— , , Ctrl+C , , :
 Signal.trap("SIGINT") do FileUtils.rm output_file exit 1 end 



Has sensible defaults but is configurable


, . , - . , -- .

. , — -.
, . , ( ), . , . , — , . ( --use-nonstandard-mode -u ).

. « -- »? , . , . - (, --no-scheme --gzip ), db_backup my_db .
, . db_backup --scheme my_db , . , , , , -
 --login , --password , --host , --force , , -. , , - .

~/.myapp.rc . , . -. — . — . .rc — .
? , . YAML. :
 --- :gzip: false :force: true :user: "Bob" :password: "Secr3t!" 


, .
 require 'yaml' require 'optparse' #  - options = { :gzip => true, :force => false } #     # (     ,    HOME) CONFIG_FILE = File.join(ENV['HOME'],'.db_backup.rc.yaml') if File.exists? CONFIG_FILE #     config_options = YAML.load_file(CONFIG_FILE) #     -     options.merge!(config_options) end #       #       ,    option_parser = OptionParser.new do |opts| #    . #__FILE__    ,        opts.banner = "Usage: #{__FILE__} [options] <db_name>" #   -u  --username   ,     opts.on("-u USER", "--username", "Database username, in first.last format") do |user| options[:user] = user end #     ,      opts.on("-p PASSWORD", "--password", "Database password") do |password| options[:password] = password end #     ,     .   ,   . #   --gzip      true. #      ,     - #     false     --no-gzip opts.on("--[no-]gzip", "Compress or not the backup file") do |gzip| options[:gzip] = gzip end end #       ,    option_parser. #    ARGV    , #        options # (     ) option_parser.parse!(ARGV) #    db_name = ARGV.shift 


— . , — .
 --- :filename: ~/.todo.txt :url: http://jira.example.com :username: davec :password: S3cr3tP@ss :commands: :new: :f: true :group: Analytics Database :list: :format: pretty :done: {} 


, YAML — . , — . , , gem rspec, git.

Installs painlessly


, . , rubygems — , :
gem install/update gemname

— , , , , ( ). - rubygems.org . , , (, , ) gem .
gem install , rubygems , ( ) . , , , ( -, ). , . , rails 2.3.8 rails 3.2, activesupport-, , .

, , , — . , , ruby .
, . « ». : Major.Minor.Patch. — - . API, -. , . , , , : 1.13.2.
, , - minor-. , , , . , API, .

— . , bin , ( bundler -). .../ruby/bin - ( , -, , ). , ruby PATH — . .
Windows , , — bat-, . , .

?
-, -, .rb. Unix, Windows. , .
-, : #!/usr/bin/env ruby
, /usr/bin/ruby . env , , rvm.
-, , lib/my_exec.rb, require. , . :
 #!/usr/bin/env ruby require 'rubygems' #    ruby 1.9   require 'your-gem' require 'your-gem/my_exec' 


, -? , , . , my_app value1 value2 . ? , ['value1', 'value2'] . ? Unix , . Windows , .. my_app Windows, , ( ruby.exe). , , , ruby. ぀たり : ruby my_app value1 value2 , ruby, , .

, , rubygems bat-? bat- , . rubygems . : . Hello World . , , ( , Windows- , Unix-). , , , rspec. git- ( , ruby). , Windows, - — .


Fails gracefully


.
. stderr , (, , ). , . - , .
- , , ? , , . , , --force . , .
? , . rm -rf * .log , , , .


Gets new features and bug fixes easily


— , . , , . , . , , . 

, , ( ) . , , . ( HDD — ). - .
— aruba , Cucumber CLI. , , , , , - .
( ) — TestUnit rspec- fakefs . , , — , , . mock- , File , Dir ( ) , , . . 矎人 , ( , Kernel.system , ) lib/my_exec .

, aruba, , ? stdout stderr StringIO . «». : out, err = MiniTest::Assertions.capture_io{ ... } , , .
! -: STDOUT $stdout . StringIO, , . , warning, , . , puts - , .
, ( STDOUT.puts 'smth' ), , , STDOUT , STDIN STDERR .

. , . ARGV . , , ? : . shellwords String#shellsplit .
, , , , ARGV : ARGV.replace(new_array) .
, OptionParser#parse! 。 ARGV OptionParser#parse!(new_array) , , ARGV . , — .

— . . .

Delights users


.

テヌブル

, : , , , . : . — terminal-table .

色

, . . : /. - . — rainbow term-ansicolor . , . , — — . Windows- , . , .

, 10% . , , . diff , . , , , .
! machine-readable — , . , , « » .


. Readline, . , : . rubygems thor , say ask.
? irb rails console. : , JSON- , . JSON, cd, ls, rm mknode. , . .


, , . , , . : ? ? , ? , , stderr - ( , , flush , - , ).
! , . \r — . \r , (, «» ). , puts , .. . print , :
 (0..100).each do |i| $stderr.print("\r#{i}% done") sleep(0.1) end 

, , : stderr stdout , , .

.


-, rake , thor . — , DSL , .

Rake — make ruby. Rakefile . , bundler Rakefile : build, install, release, . rake — rake release build release. , rake , . , , rake.

Thor — rake. «» . .
, , . . , Ruby on Rails , , .

OptionParser ruby. , . , , — , . , OptionParser , ( — . ) .
OptionParser : ( ; , , , git). OptionParser- ( , ) — . , , — .

GLI . , . .

, , — docopt . — , , OptionParser . python . . , , .

PS , , , ARGF . — , ARGF — .

Source: https://habr.com/ru/post/J150950/


All Articles