2008-10-03 7 views
156

Ho alcune semplici attività di scripting della shell che desidero fareCome si usa Ruby per lo scripting della shell?

Ad esempio: selezione di un file nella directory di lavoro da un elenco di file che corrispondono ad alcune espressioni regolari.

So che posso fare questo genere di cose usando standard bash e grep ma sarebbe bello poter hackerare script veloci che funzioneranno in windows e linux senza che io debba memorizzare un mucchio di programmi da riga di comando e bandiere ecc

ho cercato di ottenere questo andare, ma ha finito per ottenere confuso su dove dovrei ottenere informazioni come un riferimento alla directory corrente

Quindi la domanda è quali parti delle librerie Ruby fanno ho bisogno sapere di scrivere script di shell rubino?

+2

Probabilmente non è una buona risposta, ma Rubino pratica per l'amministratore del sistema è un ottimo riferimento. http://www.amazon.com/Practical-System-Administration-Experts-Source/dp/1590598210/ref=sr_1_1?s=books&ie=UTF8&qid=1346355414&sr=1-1&keywords=ruby+per+system+amministrazione – exiquio

risposta

141

Per impostazione predefinita, è già possibile accedere a Dir e File, che sono piuttosto utili da soli.

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 

utile anche dal 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) 

che è piuttosto bello

4

"Come scrivo rubino" è un po 'oltre lo scopo di SO.

Ma per trasformare questi script Ruby in script eseguibili, mettere questa come prima linea del vostro script ruby:

#!/path/to/ruby 

quindi apportare le file eseguibile:

chmod a+x myscript.rb 

e si va via.

9

diciamo che scrivi lo script script.rb. mettere:

#!/usr/bin/env ruby 

come la prima linea e fare un chmod +x script.rb

4

Posizionare questo all'inizio del vostro script.rb

#!/usr/bin/env ruby 

Poi segnare come eseguibile:

chmod +x script.rb 
103

Come già detto dagli altri, la prima riga deve essere

#!/usr/bin/env ruby 

E si hanno anche per renderlo eseguibile: (nella shell)

chmod +x test.rb 

Quindi segue il codice Ruby. Se si apre un file

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

il file viene aperto nella directory corrente si otterrebbe con pwd nel guscio.

Anche il percorso del tuo script è semplice da ottenere. Con $0 ottieni il primo argomento della shell, che è il percorso relativo al tuo script. Il percorso assoluto può essere determinato così:

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

Per le operazioni del file system ho quasi sempre uso percorso. Questo è un wrapper per molte altre classi correlate al file system. Utile anche: Dir, File ...

3

In ruby, la costante __FILE__ ti darà sempre il percorso dello script che stai eseguendo.

Su Linux, /usr/bin/env è tuo amico:

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

In Windows Dipende se i file .RB sono associati con rubino. Se sono:

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

Se non lo sono, si deve richiamare esplicitamente rubino su di loro, io uso un file .cmd intermedio:

my_script.cmd:

@ruby %~dp0\my_script.rb 

mio_script .RB:

puts File.expand_path(__FILE__) 
21

andare a prendere una copia di Everyday Scripting with Ruby . Ha un sacco di consigli utili su come fare i tipi di cose che vuoi fare.

+1

Buon libro , Lo sto leggendo in questo momento: sembra un viaggio in codice zen. E se non conosci TDD, imparerai le basi di TDD lungo la strada. –

+0

Penso che il libro abbia delle buone informazioni ma molto sovraccarico per i programmatori esperti. –

12

Questo potrebbe anche essere utile: http://rush.heroku.com/

non ho usato molto, ma sembra piuttosto cool

Dal sito:

rush è un sostituto della shell unix (bash, zsh, ecc.) Che utilizza la pura sintassi Ruby. Grep attraverso i file, trovare e uccidere i processi, copiare i file - tutto quello che fai nella shell, ora in Ruby

+2

Rush: no. Perché? http://groups.google.com/group/ruby-shell/browse_thread/thread/75c8cea757d2f680# È fantastico ma non c'è nessuno al volante. –

65

Ecco qualcosa di importante che manca dalle altre risposte: i parametri della riga di comando sono esposti allo script di shell di Ruby attraverso l'array ARGV (globale).

Quindi, se si ha uno script chiamato my_shell_script:

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

...renderlo eseguibile (come altri hanno detto):

chmod u+x my_shell_script 

e chiamarlo in questo modo:

> ./my_shell_script one two three four five 

si otterrebbe in questo modo:

I was passed: 
one 
two 
three 
four 
five 

Gli argomenti funzionano bene con l'espansione dei nomi :

./my_shell_script * 

I was passed: 
a_file_in_the_current_directory 
another_file  
my_shell_script 
the_last_file 

La maggior parte di questo funziona solo su UNIX (Linux, Mac OS X), ma puoi fare cose simili (anche se meno convenienti) in Windows.

30

C'è un sacco di buoni consigli qui, quindi ho voluto aggiungere un po 'di più.

  1. backtick (o back-zecche) consentono di fare alcune cose di scripting molto più facile. Considerare

    puts `find . | grep -i lib` 
    
  2. Se si esegue in problemi con ottenere l'uscita del backticks, la roba sta per err standard invece di standard out. Use this advice

    out = `git status 2>&1` 
    
  3. backtick fanno stringa di interpolazione:

    blah = 'lib' 
    `touch #{blah}` 
    
  4. You can pipe inside Ruby, too. È un collegamento al mio blog, ma si collega qui, quindi va bene :) Ci sono probabilmente cose più avanzate là fuori su questo argomento.

  5. Come altre persone notato, se si vuole fare sul serio non c'è Rush: non solo come una sostituzione della shell (che è un po 'troppo divertente e adatto a me), ma anche as a library for your use in shell scripts and programs.


On Mac, usa Applescript all'interno di Ruby per maggiore potenza. Ecco il mio shell_here script:

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

`osascript -e "${cmd}"` 
+0

Ho dovuto indentare il codice 4 ulteriori spazi per la formattazione. Ho anche rimandato indietro i backtick, ma non conosco molto bene Ruby, quindi ti consigliamo di verificare che sia quello che intendi. –

+0

@Bill the Lizard, sì, quello era il "trucco" di cui avevo bisogno: i doppi indent. GRAZIE PER L'AIUTO. –

+1

Penso che Rush sia morto: http://groups.google.com/group/ruby-shell/browse_thread/thread/1f856f6960165309# –

3

La risposta da webmat è perfetto. Voglio solo indicarti un'aggiunta. Se devi gestire molto con i parametri della riga di comando per i tuoi script, devi usare optparse. È semplice e ti aiuta moltissimo.

6

Quando si desidera scrivere script rubino più complessi, questi strumenti possono aiutare:

Ad esempio:

  • thor (un quadro di scripting)

  • gli (git come l'interfaccia)

  • methadone (per la creazione di strumenti semplici)

Iniziano a scrivere i propri script, in particolare "l'app della riga di comando".

3

La risposta sopra è interessante e molto utile quando si utilizza Ruby come script di shell. Per me, io non uso Ruby come linguaggio quotidiano e preferisco usare ruby ​​solo come controllo di flusso e continuo a utilizzare bash per eseguire le attività.

Alcuni funzione di supporto può essere utilizzato per risultato dell'esecuzione test

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

Con aiutante, lo script Ruby potrebbe essere bash simili:

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