web-dev-qa-db-ja.com

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

簡単なシェルスクリプトタスクがいくつかあります。

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

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

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

それで、質問はRubyライブラリのどの部分をRubyシェルスクリプトを書くために知る必要があるのでしょうか?

162
Willbill

デフォルトでは、すでに Dir および File にアクセスできますが、これらは単独で非常に便利です。

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)

かなりいいですね

145
webmat

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

#!/usr/bin/env Ruby

また、実行可能にする必要があります:(シェルで)

chmod +x test.rb

その後、Rubyコードに従います。ファイルを開く場合

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 ...

109
Georg Schölly

他の回答から欠落している重要なものがあります:コマンドラインパラメーターは、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でも同様の(便利ではありませんが)ことができます。

66
Craig Walker

ここにはたくさんの良いアドバイスがありますので、もう少し追加したいと思いました。

  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}"`
31
Dan Rosenstark

Rubyによる毎日のスクリプト作成 のコピーを入手してください。それはあなたがしたい種類のことをする方法に関するたくさんの役に立つヒントを持っています。

21
Aaron Hinni

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

あまり使いませんが、かなりかっこいい

サイトから:

Rushは、純粋なRuby構文を使用するUNIXシェル(bash、zshなど)の代替です。ファイルをGrepし、プロセスを見つけて強制終了し、ファイルをコピーします-シェルで行うことはすべて、現在はRubyで行います

12
craigp

script.rbスクリプトを書いたとしましょう。プット:

#!/usr/bin/env Ruby

最初の行としてchmod +x script.rbを実行します

10
Vasil

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

例えば:

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

  • gli (git like interface)

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

独自のスクリプト、特に「コマンドラインアプリ」をすばやく作成できます。

6
Bohr

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
Houcheng

これをscript.rbの先頭に配置します

#!/usr/bin/env Ruby

次に、実行可能としてマークします。

chmod +x script.rb
4

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

ただし、これらのRubyスクリプトを実行可能スクリプトにするには、これをRubyスクリプトの最初の行として追加します。

#!/path/to/Ruby

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

chmod a+x myscript.rb

そして離れて行く。

4

webmat による答えは完璧です。私はあなたに追加を指摘したいだけです。スクリプトのコマンドラインパラメーターを多く処理する必要がある場合は、 optparse を使用する必要があります。シンプルであり、非常に役立ちます。

3
awenkhh

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ファイルがRubyに関連付けられているかどうかによって異なります。それらが:

# 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__)
3
bltxd