Rubyをシェルスクリプトに使用するにはどうすればよいですか?


165

やりたい簡単なシェルスクリプトタスクがあります。

例:正規表現に一致するファイルのリストから、作業ディレクトリ内のファイルを選択します。

標準のbashとgrepを使用してこの種のことを実行できることはわかっていますが、コマンドラインプログラムやフラグなどのヒープを覚えておく必要がなく、WindowsやLinuxで機能するクイックスクリプトをハックできるといいですね。

これを実行しようとしましたが、現在のディレクトリへの参照などの情報をどこで取得する必要があるかについて混乱しました

問題は、Rubyシェルスクリプトを作成するために、Rubyライブラリのどの部分を知る必要があるかということです。


3
おそらく良い答えではありませんが、システム管理のための実用的なRubyは優れたリファレンスです。amazon.com/Practical-System-Administration-Experts-Source/dp/...
exiquio

回答:


148

デフォルトでは、すでにDirFileにアクセスできます。これらは、それ自体で非常に便利です。

Dir['*.rb'] #basic globs
Dir['**/*.rb'] #** == any depth of directory, including current dir.
#=> array of relative names

File.expand_path('~/file.txt') #=> "/User/mat/file.txt"
File.dirname('dir/file.txt') #=> 'dir'
File.basename('dir/file.txt') #=> 'file.txt'
File.join('a', 'bunch', 'of', 'strings') #=> 'a/bunch/of/strings'

__FILE__ #=> the name of the current file

stdlibからも便利なのはFileUtilsです

require 'fileutils' #I know, no underscore is not ruby-like
include FileUtils
# Gives you access (without prepending by 'FileUtils.') to
cd(dir, options)
cd(dir, options) {|dir| .... }
pwd()
mkdir(dir, options)
mkdir(list, options)
mkdir_p(dir, options)
mkdir_p(list, options)
rmdir(dir, options)
rmdir(list, options)
ln(old, new, options)
ln(list, destdir, options)
ln_s(old, new, options)
ln_s(list, destdir, options)
ln_sf(src, dest, options)
cp(src, dest, options)
cp(list, dir, options)
cp_r(src, dest, options)
cp_r(list, dir, options)
mv(src, dest, options)
mv(list, dir, options)
rm(list, options)
rm_r(list, options)
rm_rf(list, options)
install(src, dest, mode = <src's>, options)
chmod(mode, list, options)
chmod_R(mode, list, options)
chown(user, group, list, options)
chown_R(user, group, list, options)
touch(list, options)

それはかなりいいです


110

他の人がすでに言ったように、あなたの最初の行は

#!/usr/bin/env ruby

そして、それを実行可能にする必要もあります:(シェルで)

chmod +x test.rb

次にルビコードに従います。ファイルを開いた場合

File.open("file", "r") do |io|
    # do something with io
end

ファイルはpwd、シェルで取得する現在のディレクトリで開かれます。

スクリプトへのパスも簡単に取得できます。では$0、あなたのスクリプトへの相対パスであるシェルの最初の引数を取得します。絶対パスは次のように決定できます。

#!/usr/bin/env ruby
require 'pathname'
p Pathname.new($0).realpath()

ファイルシステムの操作では、ほとんどの場合パス名を使用します。これは、他の多くのファイルシステム関連クラスのラッパーです。また有用:Dir、File ...


66

他の答えには欠けている重要なものを次に示します。コマンドラインパラメータは、ARGV(グローバル)配列を介してRubyシェルスクリプトに公開されます。

したがって、my_shell_scriptというスクリプトがある場合は、次のようにします。

#!/usr/bin/env ruby
puts "I was passed: "
ARGV.each do |value|
  puts value
end

...実行可能にする(他の人が述べたように):

chmod u+x my_shell_script

そして、次のように呼び出します。

> ./my_shell_script one two three four five

あなたはこれを得るでしょう:

I was passed: 
one
two
three
four
five

引数はファイル名展開でうまく機能します:

./my_shell_script *

I was passed: 
a_file_in_the_current_directory
another_file    
my_shell_script
the_last_file

これのほとんどはUNIX(Linux、Mac OS X)でのみ機能しますが、Windowsでも同様の(便利ではありません)ことができます。


32

ここには良いアドバイスがたくさんあるので、もう少し追加したかったのです。

  1. バックティック(またはバックティック)を使用すると、スクリプトを簡単に実行できます。検討する

    puts `find . | grep -i lib`
  2. バックティックの出力を取得する際に問題が発生した場合、標準出力ではなく標準エラーになります。このアドバイスを使用

    out = `git status 2>&1`
  3. バックティックは文字列補間を行います:

    blah = 'lib'
    `touch #{blah}`
  4. Rubyの内部でもパイプできます。これは私のブログへのリンクですが、ここにリンクしているので問題ありません。

  5. 他の人が指摘したように、真剣に取り組みたい場合は、Rushがあります。それは、シェル置換(私にとっては少しおかしすぎる)としてだけでなく、シェルスクリプトやプログラムで使用するためのライブラリとしてです。


Macでは、Ruby内でApplescriptを使用して、より強力にしてください。これが私のshell_hereスクリプトです:

#!/usr/bin/env ruby
`env | pbcopy` 
cmd =  %Q@tell app "Terminal" to do script "$(paste_env)"@
puts cmd

`osascript -e "${cmd}"`

コードをインデントするだけで、4つのスペースがフォーマットされます。また、バックティックを元に戻しましたが、Rubyについてはあまりよく知りません。そのため、Rubyが意図したとおりであることを確認する必要があります。
トカゲに請求

@Bill Lizard、ええ、それは私が必要としていた「トリック」でした:二重インデント。助けてくれてありがとう。
Dan Rosenstark、2010年

1
私はラッシュが死んでいると思う:groups.google.com/group/ruby-shell/browse_thread/thread/...
ダンRosenstark

22

Rubyを使用したEveryday Scriptingを入手してください。それはあなたがしたいタイプのことをする方法についてのたくさんの役に立つヒントを持っています。


2
良い本です。今読んでいます。禅のコードの旅のようです。TDDがわからない場合は、途中でTDDの基本を学びます。
セバスチャンロッカセラー

この本にはいくつかの良い情報があると思いますが、経験豊富なプログラマにとってはかなりのオーバーヘッドになります。
Dが2014年

12

これも役に立つかもしれません:http : //rush.heroku.com/

あまり使っていませんが、かっこいいです

サイトから:

rushは、純粋なRuby構文を使用するUNIXシェル(bash、zshなど)に代わるものです。ファイルのグレップ、プロセスの検索と強制終了、ファイルのコピー-シェルで行うすべての作業、今はRubyで


2
ラッシュ:いいえ。どうして?groups.google.com/group/ruby-shell/browse_thread/thread/…すばらしいですが、誰も操作しません。
Dan Rosenstark、

12

script.rbスクリプトを作成するとします。置く:

#!/usr/bin/env ruby

最初の行として、 chmod +x script.rb


7

より複雑なルビスクリプトを記述したい場合、これらのツールが役立ちます。

例えば:

  • thor(スクリプトフレームワーク)

  • gli(gitのようなインターフェイス)

  • メタドン(シンプルなツールを作成するため)

彼らはあなたにあなた自身のスクリプト、特に「コマンドラインアプリ」を書くためのクイックスタートを与えます。


5

上記の回答は興味深いもので、Rubyをシェルスクリプトとして使用する場合に非常に役立ちます。私にとって、私は日常の言語としてRubyを使用していません。フロー制御としてのみRubyを使用し、bashを使用してタスクを実行することを好みます。

一部のヘルパー関数は、実行結果のテストに使用できます

#!/usr/bin/env ruby
module ShellHelper
  def test(command)
    `#{command} 2> /dev/null`
    $?.success?
  end

  def execute(command, raise_on_error = true)
    result = `#{command}`
    raise "execute command failed\n" if (not $?.success?) and raise_on_error
    return $?.success?
  end

  def print_exit(message)
    print "#{message}\n"
    exit
  end

  module_function :execute, :print_exit, :test
end

ヘルパーがあれば、rubyスクリプトも同様にbashになります。

#!/usr/bin/env ruby
require './shell_helper'
include ShellHelper

print_exit "config already exists" if test "ls config"

things.each do |thing|
  next if not test "ls #{thing}/config"
  execute "cp -fr #{thing}/config_template config/#{thing}"
end

男、これは素晴らしいです、ありがとう!
ビクターマーティンズ

4

「ルビの書き方」はSOの範囲を少し超えています。

しかし、これらのルビスクリプトを実行可能スクリプトに変換するには、これをルビスクリプトの最初の行として記述します。

#!/path/to/ruby

次に、ファイルを実行可能にします。

chmod a+x myscript.rb

離れて行きます。



3

ウェブマットによる答えは完璧です。私はあなたに追加を指摘したいだけです。スクリプトのコマンドラインパラメータをたくさん扱う必要がある場合は、optparseを使用する必要があります。それはシンプルで、あなたを途方もなく助けます。


3

Rubyでは、定数__FILE__は常に実行中のスクリプトのパスを提供します。

Linuxでは、/usr/bin/envあなたの友達は:

#! /usr/bin/env ruby
# Extension of this script does not matter as long
# as it is executable (chmod +x)
puts File.expand_path(__FILE__)

Windowsでは、.rbファイルがルビに関連付けられているかどうかによって異なります。それらが:

# This script filename must end with .rb
puts File.expand_path(__FILE__)

そうでない場合は、明示的にrubyを呼び出す必要があります。中間の.cmdファイルを使用します。

my_script.cmd:

@ruby %~dp0\my_script.rb

my_script.rb:

puts File.expand_path(__FILE__)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.