Kabuk komut dosyası oluşturmak için Ruby'yi nasıl kullanırım?


165

Yapmak istediğim bazı basit kabuk komut dosyası görevlerim var

Örneğin: Normal bir ifadeyle eşleşen dosyaların listesinden çalışma dizinindeki bir dosyayı seçme.

Standart bash ve grep kullanarak bu tür bir şey yapabilirim biliyorum ama komut satırı programları ve bayrakları bir yığın ezberlemek zorunda kalmadan windows ve linux çalışacak hızlı komutları kesmek mümkün olmak güzel olurdu.

Bu devam etmeye çalıştım ama nerede geçerli dizine bir başvuru gibi bilgi almak gerekir hakkında karışmaya sona erdi

Soru şu: Ruby kütüphanelerinin hangi bölümlerini ruby ​​shell betikleri yazmak için bilmem gerekiyor?


3
Muhtemelen iyi bir cevap değil, ama Sistem Yönetimi için Pratik Ruby harika bir referans. amazon.com/Practical-System-Administration-Experts-Source/dp/...
exiquio

Yanıtlar:


148

Varsayılan olarak, kendi başlarına oldukça kullanışlı olan Dir ve Dosya'ya zaten erişiminiz vardır.

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

Ayrıca stdlib FileUtils yararlıdır

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)

Hangisi çok güzel


110

Diğerlerinin söylediği gibi, ilk satırınız

#!/usr/bin/env ruby

Ve ayrıca çalıştırılabilir yapmalısınız: (kabukta)

chmod +x test.rb

Sonra yakut kodunu izler. Bir dosya açarsanız

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

dosya pwdkabukta alacağınız geçerli dizinde açılır .

Senaryonuzun yolunu bulmak da kolaydır. İle $0size Betiğinize göreli bir yoldur kabuk, ilk argüman olsun. Mutlak yol şu şekilde belirlenebilir:

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

Dosya sistemi işlemleri için neredeyse her zaman Pathname kullanıyorum. Bu, diğer dosya sistemi ile ilgili sınıfların çoğu için bir sarıcıdır. Ayrıca yararlı: Dir, Dosya ...


66

Diğer cevaplardan eksik olan önemli bir şey var: komut satırı parametreleri ARGV (global) dizisi aracılığıyla Ruby kabuk betiğinize maruz kalır.

Yani, my_shell_script adında bir komut dosyanız varsa:

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

... çalıştırılabilir yap (diğerlerinin de belirttiği gibi):

chmod u+x my_shell_script

Ve şöyle deyin:

> ./my_shell_script one two three four five

Bunu elde edersiniz:

I was passed: 
one
two
three
four
five

Argümanlar, dosya adı genişletmesiyle güzel çalışır:

./my_shell_script *

I was passed: 
a_file_in_the_current_directory
another_file    
my_shell_script
the_last_file

Bunların çoğu yalnızca UNIX (Linux, Mac OS X) üzerinde çalışır, ancak Windows'ta benzer şeyleri (daha az kullanışlı olsa da) yapabilirsiniz.


32

Burada çok iyi tavsiyeler var, bu yüzden biraz daha eklemek istedim.

  1. Geri tıklamalar (veya geri tıklamalar) bazı komut dosyası işlemlerini çok daha kolay yapmanızı sağlar. Düşünmek

    puts `find . | grep -i lib`
  2. Ters çentiklerin çıktısını almakta sorun yaşarsanız, şeyler standart çıkış yerine standart hataya gider. Bu tavsiyeyi kullanın

    out = `git status 2>&1`
  3. Backticks dize enterpolasyonu yapar:

    blah = 'lib'
    `touch #{blah}`
  4. Ruby'nin içinde boru da yapabilirsiniz . Bu benim bloguma bir link, ama buraya bağlantı veriyor, bu yüzden tamam :) Bu konuda muhtemelen daha gelişmiş şeyler var.

  5. Diğer insanların belirttiği gibi, ciddi olmak istiyorsanız Rush var: sadece bir kabuk değiştirme olarak (benim için biraz fazla zany) değil, aynı zamanda kabuk komut dosyalarında ve programlarda kullanımınız için bir kütüphane olarak.


Mac'te, daha fazla güç için Ruby içindeki Applescript'i kullanın. İşte benim shell_heresenaryom:

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

`osascript -e "${cmd}"`

Ben sadece biçimlendirilmesi için kod 4 boşluk daha girintilemek zorunda kaldı. Ben de ters çivileri geri koydum, ama Ruby'yi çok iyi tanımıyorum, bu yüzden amaçladığından emin olmak isteyeceksin.
Kertenkele Bill

@ Kertenkele'yi faturalandır, evet, ihtiyacım olan 'numara': çift girintiler. YARDIM İÇİN TEŞEKKÜRLER.
Dan Rosenstark


22

Kendinize Ruby ile Günlük Komut Dosyalarının bir kopyasını alın . Yapmak istediğiniz şeylerin nasıl yapılacağı konusunda birçok yararlı ipucu var.


2
İyi kitap, şu anda okuyorum: Zen kodu yolculuğu gibi geliyor. Eğer TDD'yi bilmiyorsanız, TDD'nin temellerini öğreneceksiniz.
Sébastien RoccaSerra

Bence kitabın bazı iyi bilgileri var ama deneyimli programcılar için çok fazla yükü var.
D


12

diyelim ki script.rbsenaryonuzu yazıyorsun . koymak:

#!/usr/bin/env ruby

ilk satır olarak ve bir chmod +x script.rb


7

Daha karmaşık yakut komut dosyaları yazmak istediğinizde, bu araçlar yardımcı olabilir:

Örneğin:

  • thor (bir betik çerçevesi)

  • gli (git benzeri arayüz)

  • metadon (basit araçlar oluşturmak için)

Kendi komut dosyalarınızı, özellikle de 'komut satırı uygulaması'nı yazmaya hızlı bir başlangıç ​​sağlarlar.


5

Yukarıdaki cevap Ruby'yi kabuk betiği olarak kullanırken ilginç ve çok faydalıdır. Benim için Ruby'yi günlük dilim olarak kullanmıyorum ve ruby'i sadece akış kontrolü olarak kullanmayı ve yine de görevleri yapmak için bash'ı kullanmayı tercih ediyorum.

Bazı yardımcı işlev yürütme sonucunu test etmek için kullanılabilir

#!/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

Yardımcı ile, yakut senaryo benzer olabilir:

#!/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

Dostum, bu harika, teşekkürler!
Victor Martins

4

"Nasıl yakut yazarım" SO kapsamının biraz ötesindedir.

Ancak bu yakut komut dosyalarını yürütülebilir komut dosyalarına dönüştürmek için, bunu yakut komut dosyanızın ilk satırı olarak koyun:

#!/path/to/ruby

Ardından dosyayı yürütülebilir yapın:

chmod a+x myscript.rb

ve uzağa gidiyorsun.


4

Bunu script.rb dosyasının başına yerleştirin

#!/usr/bin/env ruby

Ardından yürütülebilir olarak işaretleyin:

chmod +x script.rb

3

Webmat'ın yanıtı mükemmel. Sizi sadece bir ilaveye yönlendirmek istiyorum. Komut dosyalarınız için komut satırı parametreleriyle çok uğraşmanız gerekiyorsa, optparse kullanmalısınız . Çok basit ve muazzam bir şekilde yardımcı olur.


3

Ruby'de, sabit __FILE__size her zaman çalıştırdığınız komut dosyasının yolunu verecektir.

Linux'ta /usr/bin/envarkadaşınız:

#! /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'ta .rb dosyalarının ruby ​​ile ilişkili olup olmamasına bağlıdır. Eğer öylelerse:

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

Değilse, açıkça onlara yakut çağırmanız gerekir, bir ara .cmd dosyası kullanıyorum:

my_script.cmd:

@ruby %~dp0\my_script.rb

my_script.rb:

puts File.expand_path(__FILE__)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.