sintaxis - ¿Cómo uso Ruby para scripts de shell?
ruby uso (13)
"Cómo escribo ruby" está un poco más allá del alcance de SO.
Pero para convertir estos scripts de ruby en scripts ejecutables, coloca esto como la primera línea de tu script de ruby:
#!/path/to/ruby
Luego haz que el archivo sea ejecutable:
chmod a+x myscript.rb
y lejos tu vas.
Tengo algunas tareas sencillas de creación de scripts que quiero hacer
Por ejemplo: Seleccionar un archivo en el directorio de trabajo a partir de una lista de archivos que coincidan con alguna expresión regular.
Sé que puedo hacer este tipo de cosas utilizando bash y grep estándar, pero me gustaría ser capaz de hackear guiones rápidos que funcionarán en Windows y Linux sin que tenga que memorizar un montón de programas de línea de comandos, banderas, etc.
Traté de poner esto en marcha, pero terminé confundido acerca de dónde debería obtener información, como una referencia al directorio actual
Entonces, la pregunta es: ¿qué partes de las bibliotecas de Ruby necesito saber para escribir las secuencias de comandos de Ruby Shell?
Aquí hay algo importante que falta en las otras respuestas: los parámetros de línea de comandos están expuestos a su script de shell de Ruby a través de la matriz ARGV (global).
Entonces, si tuviera un script llamado my_shell_script:
#!/usr/bin/env ruby
puts "I was passed: "
ARGV.each do |value|
puts value
end
... hacerlo ejecutable (como otros lo han mencionado):
chmod u+x my_shell_script
Y llámalo así:
> ./my_shell_script one two three four five
Tendrás esto:
I was passed:
one
two
three
four
five
Los argumentos funcionan bien con la expansión del 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.
Aquí hay muchos buenos consejos, así que quería agregar un poquito más.
Los Backticks (o back-ticks) te permiten hacer mucho más fácil las secuencias de comandos. Considerar
puts `find . | grep -i lib`
Si tiene problemas para obtener el resultado de los backticks, las cosas van a errar estándar en lugar de estándar. Usa este consejo
out = `git status 2>&1`
Backticks hacen interpolación de cadenas:
blah = ''lib'' `touch #{blah}`
También puedes conectar dentro de Ruby . Es un enlace a mi blog, pero tiene enlaces aquí, así que está bien :) Probablemente haya cosas más avanzadas sobre este tema.
Como otras personas notaron, si quieres ponerte serio, hay Rush: no solo como un reemplazo de shell (que es un poco demasiado estrafalario para mí) sino también como una biblioteca para tu uso en scripts y programas de shell.
En Mac, usa Applescript dentro de Ruby para obtener más poder. Aquí está mi script de shell_here
:
#!/usr/bin/env ruby
`env | pbcopy`
cmd = %Q@tell app "Terminal" to do script "$(paste_env)"@
puts cmd
`osascript -e "${cmd}"`
Coloque esto al comienzo de su script.rb
#!/usr/bin/env ruby
Luego márcalo como ejecutable:
chmod +x script.rb
Como los otros ya lo han dicho, tu primera línea debería ser
#!/usr/bin/env ruby
Y también tienes que hacerlo ejecutable: (en el shell)
chmod +x test.rb
Luego sigue el código ruby. Si abre un archivo
File.open("file", "r") do |io|
# do something with io
end
el archivo se abre en el directorio actual que obtendría con pwd
en el shell.
La ruta a su 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 ...
Cuando desee escribir scripts de ruby más complejos, estas herramientas pueden ayudar:
Por ejemplo:
Le dan un comienzo rápido para escribir sus propios scripts, especialmente la ''aplicación de línea de comando''.
En ruby, la constante __FILE__
siempre te dará la ruta del script que estás ejecutando.
En Linux, /usr/bin/env
es tu 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 si los archivos .rb están asociados o no con ruby. Si ellos estan:
# This script filename must end with .rb
puts File.expand_path(__FILE__)
Si no lo son, tienes que invocar explícitamente Ruby sobre ellos, utilizo un archivo intermedio .cmd:
my_script.cmd:
@ruby %~dp0/my_script.rb
my_script.rb:
puts File.expand_path(__FILE__)
Esto también podría ser útil: http://rush.heroku.com/
No lo he usado mucho, pero se ve muy bien
Desde el sitio:
rush es un reemplazo para el shell unix (bash, zsh, etc.) que usa la sintaxis pura de Ruby. Recorre archivos, busca y elimina procesos, copia archivos, todo lo que haces en el shell, ahora en Ruby
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.
Se puede usar alguna función auxiliar para probar el resultado de la ejecución
#!/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 ayuda, el script de ruby podría ser similar:
#!/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
La respuesta por es perfecta. 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.
Obtenga una copia de Everyday Scripting con Ruby . Tiene muchos consejos útiles sobre cómo hacer los tipos de cosas que quiere hacer.
Por defecto, ya tiene acceso a Dir y a 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 útil desde 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
digamos que escribes tu script script.rb
. poner:
#!/usr/bin/env ruby
como la primera línea y hacer una chmod +x script.rb