シェルスクリプトに適した優れた言語、Ruby
(lucasoshiro.github.io)- Rubyは主にRailsフレームワークと結び付けて語られることが多く、この言語の優れた点が見過ごされがち
- Rubyは非常に豊富で完成度の高い言語であり、特に複雑なシェルスクリプトを書くときに役立つ
- この記事の目的
- シェルスクリプトを書く際に便利なRubyの機能を示し、BashおよびPythonと比較する
- BashスクリプトをRubyスクリプトで完全に置き換えることが目的ではない
機能 1: 外部コマンドの呼び出し
- Rubyで外部コマンドを呼び出すときはバッククォート(```)を使う。
- たとえば、バッククォートを使うと外部コマンドの出力を変数に保存できる。
systemまたはpopenを使うこともできる。`ls`- コマンドの出力を変数に保存できる。
my_date=`date`
機能 2: ステータスコード
$?変数を使って最後のコマンドのステータスコードを確認できる- Bashと非常によく似ている
`true` puts $? # 0 `false` puts $? # 1
機能 3: 型のある言語
- Rubyは静的型付け言語ではないが、型を持っている。
- オブジェクト指向言語であり、すべてがオブジェクトとして扱われる。
- Bashと違って、文字列以外の型も安全に使える。
total_lines = `wc -l my_file`.to_i # ファイルの行数を含む整数 half = total_lines.div 2 # 整数除算 puts `head -n #{half} my_file` # ファイルの半分を出力する
機能 4: 関数型の構成
- Rubyは
map、select(フィルタ)、reduce、flat_mapなどの関数型演算をメソッドとして実装している。 - コマンド出力に
mapを適用できる。puts `ls`.lines.map { |name| name.strip.length } # ファイル名の長さを出力する
機能 5: 正規表現マッチング
- Rubyでは正規表現は型であり、正規表現を使う演算が組み込まれている。
- たとえば、現在のgitブランチ名を取得する方法:
current_branch_regex = /^\* (\S+)/ output_lines = `git branch`.lines output_lines.each do |line| if line =~ current_branch_regex # 文字列と正規表現をマッチさせる puts $1 # 最初のグループのマッチを出力する end end
機能 6: 簡単なスレッド
- Rubyは複数のスレッドを扱うのが非常に簡単
- たとえば、複数のファイルを同時にダウンロードするときに便利
(1..10).map do |i| # 1から10まで繰り返す Thread.new do `wget http://my_site.com/file_#{i}` # コマンド内で変数を使える end end.each { |thread| thread.join } # do/end と波括弧は同じ目的を持つ
機能 7: 組み込みのファイルおよびディレクトリ操作
- Rubyではすべてのファイル操作は
Fileクラスのメソッドとして、ディレクトリ操作はDirクラスのメソッドとして提供される。 - Pythonと違って、一貫した方法でファイルとディレクトリを扱える。
exists = File.exists? 'My File' # 真偽値を返すメソッドは '?' で終わる file_content = File.open('My File').read File.delete 'My File' # 括弧は曖昧でなければ省略可能
結論
- 複雑なシェルスクリプトを置き換える際にはRubyを検討することを勧める
- もちろんBashを完全に捨てるべきという意味ではないが、複雑な作業ではRubyの方がより良い選択肢になり得る
- Python、Perl、JSなどでも可能だが、個人的にはRubyが最も完成度が高く、使いやすい言語である
GN⁺の意見
- Rubyはオブジェクト指向と関数型プログラミングの両方をサポートしており、多様なプログラミングスタイルを受け入れられる。
- Pythonと比べると、Rubyはより厳格なオブジェクト指向パラダイムに従っている。
- シェルスクリプトを書く際、複雑さが増すほどRubyの利点が際立つ。
- Rubyのスレッド処理機能は、並列作業を簡単に実装できるようにしてくれる。
- ファイルおよびディレクトリ操作が直感的かつ一貫して提供されるため、生産性が高まる。
3件のコメント
スクリプト用として使ってもよさそうですね(笑) バージョンは分かりませんが、macにも標準でインストールされていますよね……?!
かつて愛したRuby… こういう形ででも(?)多くの愛を受ける言語として残ってほしいです。
Hacker Newsの意見
binding.irbやbinding.pryを使うと、スクリプト内でインタラクティブにデバッグできる。Pathnameを使うと、Fileより自然なAPIが提供される。Parallelを使えば並列処理がさらに簡単になる。