2008-10-03 26 views
156

Tengo algunas tareas simples de creación de comandos de shell que quiero hacer¿Cómo uso Ruby para scripts de shell?

Por ejemplo: Seleccionar un archivo en el directorio de trabajo de una lista de los archivos que coinciden con algunas expresiones regulares.

Sé que puedo hacer este tipo de cosas usando bash y grep estándar, pero me gustaría ser capaz de hackear guiones rápidos que funcionarán en Windows y Linux sin tener que memorizar un montón de programas de línea de comandos y banderas, etc.

yo tratamos de obtener esta pasando pero terminaron encima de conseguir confundido acerca de donde debería estar recibiendo información como una referencia al directorio actual

Así que la pregunta es ¿qué partes de las bibliotecas de Ruby qué necesito saber escribir guiones de shell ruby?

+2

Probablemente no es una buena respuesta, pero Rubí práctica para la administración del sistema es una gran referencia. 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+for+system+administration – exiquio

Respuesta

141

De manera predeterminada, ya tiene acceso a Dir y File, que son bastante útiles por sí mismos.

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 

También es útil desde el stdlib es 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) 

lo cual es bastante agradable

4

"Cómo escribo ruby" está un poco fuera del alcance de SO.

Pero a su vez estos scripts rubí en guiones ejecutables, poner esto como la primera línea del script Ruby:

#!/path/to/ruby 

luego hacer el archivo ejecutable:

chmod a+x myscript.rb 

y ya está.

9

Digamos que usted escribe su secuencia de comandos script.rb. poner:

#!/usr/bin/env ruby 

como la primera línea y hacer un lugar chmod +x script.rb

4

esto al comienzo de su script.rb

#!/usr/bin/env ruby 

A continuación, marcarlo como ejecutable:

chmod +x script.rb 
103

Como ya han dicho los demás, su primera línea debe ser

#!/usr/bin/env ruby 

Y también hay que hacerlo ejecutable: (en la cáscara)

chmod +x test.rb 

Luego sigue el código de rubí. Si abre un archivo

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

se abre el archivo en el directorio actual se obtendría con pwd en la cáscara.

La ruta de acceso al script también es fácil de obtener. Con $0 obtienes el primer argumento del shell, que es la ruta relativa a tu script. La ruta absoluta se puede determinar así:

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

Para las operaciones del sistema de archivos, casi siempre uso Pathname. Este es un contenedor para muchas de las otras clases relacionadas con el sistema de archivos. También es útil: Dir, Archivo ...

3

En ruby, la constante __FILE__ siempre le dará la ruta del script que está ejecutando.

En Linux, /usr/bin/env es su amigo:

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

En Windows Depende de si o no los archivos .RB están asociados con rubí. Si son:

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

Si no es así, usted tiene que invocar explícitamente rubí en ellos, yo utilizo un archivo .cmd intermedia:

my_script.cmd:

@ruby %~dp0\my_script.rb 

my_script .rb:

puts File.expand_path(__FILE__) 
21

búscate una copia de Everyday Scripting with Ruby . Tiene muchos consejos útiles sobre cómo hacer los tipos de cosas que quiere hacer.

+1

Buen libro , Lo estoy leyendo ahora mismo: se siente como un viaje de código zen. Y si no conoces TDD, aprenderás los fundamentos de TDD a lo largo del camino. –

+0

Creo que el libro tiene buena información, pero es muy útil para los programadores experimentados. –

12

Esto también podría ser útil: http://rush.heroku.com/

no he utilizado mucho, pero parece muy bueno

Desde el sitio:

rush es un reemplazo para el shell unix (bash, zsh, etc.) que utiliza la sintaxis pura de Ruby. Grep a través de archivos, encontrar y matar procesos, copiar archivos - todo lo que haces en la cáscara, ahora en Ruby

+2

Rush: no. ¿Por qué? http://groups.google.com/group/ruby-shell/browse_thread/thread/75c8cea757d2f680# Es genial, pero no hay nadie al volante. –

65

aquí hay algo importante que falta en las otras respuestas: los parámetros de línea de comandos están expuestos a la secuencia de comandos shell de Rubí a través de la matriz ARGV (global).

lo tanto, si usted tenía un script llamado my_shell_script:

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

...hacerlo ejecutable (como han mencionado otros):

chmod u+x my_shell_script 

y lo llaman así:

> ./my_shell_script one two three four five 

se obtendría esto:

I was passed: 
one 
two 
three 
four 
five 

Los argumentos funcionan muy bien con la expansión de nombre de archivo :

./my_shell_script * 

I was passed: 
a_file_in_the_current_directory 
another_file  
my_shell_script 
the_last_file 

La mayor parte de esto solo funciona en UNIX (Linux, Mac OS X), pero puede hacer cosas similares (aunque menos convenientes) en Windows.

30

Aquí hay muchos buenos consejos, así que quería agregar un poquito más.

  1. Backticks (o back-ticks) le permiten hacer algo de scripting mucho más fácil. Considere

    puts `find . | grep -i lib` 
    
  2. Si se encuentra con problemas para obtener la salida de acentos abiertos, las cosas va a err estándar en lugar de la salida estándar. Use this advice

    out = `git status 2>&1` 
    
  3. invertidas hacen cadena de interpolación:

    blah = 'lib' 
    `touch #{blah}` 
    
  4. You can pipe inside Ruby, too. Es un enlace a mi blog, pero tiene enlaces aquí, así que está bien :) Probablemente haya cosas más avanzadas sobre este tema.

  5. Como otras personas anotadas, si usted quiere tomar en serio hay Rush: no sólo como un reemplazo de la cáscara (que es un poco demasiado estrafalario para mí), pero también as a library for your use in shell scripts and programs.


En Mac, usa Applescript dentro de Ruby para obtener más poder. Aquí está mi shell_here guión:

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

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

Solo tuve que aplicar sangría al código 4 espacios más para que sean formateados. También volví a poner los respaldos, pero no conozco muy bien a Ruby, así que querrás comprobar para asegurarte de que es lo que pretendías. –

+0

@Bill the Lizard, sí, ese fue el "truco" que estaba necesitando: las dobles sangrías. GRACIAS POR LA AYUDA. –

+1

Creo que Rush está muerto: http://groups.google.com/group/ruby-shell/browse_thread/thread/1f856f6960165309# –

3

La respuesta por webmat es perfecto. Solo quiero señalarte una adición. Si tiene que lidiar mucho con los parámetros de línea de comandos para sus scripts, debe usar optparse. Es simple y te ayuda muchísimo.

6

Cuando desea escribir scripts de rubí más complejas, estas herramientas pueden ayudar:

Por ejemplo:

  • thor (un marco de secuencias de comandos)

  • gli (GIT como el interfaz)

  • methadone (para crear herramientas simples)

Te dan un comienzo rápido para escribir tus propios scripts, especialmente la 'aplicación de línea de comando'.

3

La respuesta anterior es interesante y muy útil cuando se usa Ruby como script de shell. Para mí, no uso Ruby como mi lenguaje diario y prefiero usar ruby ​​como control de flujo solamente y aún usar bash para realizar las tareas.

Algunos función auxiliar se puede utilizar para resultado de la ejecución de pruebas

#!/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 ayudante, el guión de rubí podría ser golpe por igual:

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