2010-11-22 16 views
207

He instalado RubyInstaller en Windows y estoy ejecutando IMAP Sync pero necesito usarlo para sincronizar cientos de cuentas. Si pudiera pasarle estas variables a través de la línea de comando, podría automatizar todo el proceso.Pasar variables al script de Ruby a través de la línea de comando

# Source server connection info. 
SOURCE_NAME = '[email protected]' 
SOURCE_HOST = 'mail.example.com' 
SOURCE_PORT = 143 
SOURCE_SSL = false 
SOURCE_USER = 'username' 
SOURCE_PASS = 'password' 

# Destination server connection info. 
DEST_NAME = '[email protected]' 
DEST_HOST = 'imap.gmail.com' 
DEST_PORT = 993 
DEST_SSL = true 
DEST_USER = '[email protected]' 
DEST_PASS = 'password' 

Respuesta

368

Algo como esto:

ARGV.each do|a| 
    puts "Argument: #{a}" 
end 

continuación

$ ./test.rb "test1 test2" 

o

v1 = ARGV[0] 
v2 = ARGV[1] 
puts v1  #prints test1 
puts v2  #prints test2 
+62

me gustaría señalar explícitamente que argv [0] no apunta al nombre del programa, como algunos otros lenguajes. Para obtener el nombre del programa, consulte http://stackoverflow.com/questions/4834821/how-can-i-get-the-name-of-the-command-called-for-usage-prompts-in-ruby –

161

No reinventar la rueda; echa un vistazo a la biblioteca de Ruby's way-cool OptionParser.

Ofrece análisis de indicadores/interruptores, parámetros con valores opcionales o requeridos, puede analizar listas de parámetros en una sola opción y puede generar su ayuda para usted.

Además, si la información que se transfiere es bastante estática, eso no cambia entre ejecuciones, colóquela en un archivo YAML que se analiza. De esta forma, puede tener cosas que cambian cada vez en la línea de comandos y cosas que cambian ocasionalmente configuradas fuera de su código. Esa separación de datos y código es agradable para el mantenimiento.

He aquí algunos ejemplos con los que jugar:

require 'optparse' 
require 'yaml' 

options = {} 
OptionParser.new do |opts| 
    opts.banner = "Usage: example.rb [options]" 

    opts.on('-n', '--sourcename NAME', 'Source name') { |v| options[:source_name] = v } 
    opts.on('-h', '--sourcehost HOST', 'Source host') { |v| options[:source_host] = v } 
    opts.on('-p', '--sourceport PORT', 'Source port') { |v| options[:source_port] = v } 

end.parse! 

dest_options = YAML.load_file('destination_config.yaml') 
puts dest_options['dest_name'] 

Este es un archivo YAML la muestra si sus destinos son bastante estática:

--- 
dest_name: [email protected] 
dest_host: imap.gmail.com 
dest_port: 993 
dest_ssl: true 
dest_user: [email protected] 
dest_pass: password 

Esto le permitirá generar fácilmente un archivo YAML:

require 'yaml' 

yaml = { 
    'dest_name' => '[email protected]', 
    'dest_host' => 'imap.gmail.com', 
    'dest_port' => 993, 
    'dest_ssl' => true, 
    'dest_user' => '[email protected]', 
    'dest_pass' => 'password' 
} 

puts YAML.dump(yaml) 
+1

OptParse el enlace está muerto. Pruebe http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html – Casey

+6

Excelente respuesta; Puede valer la pena agregar que después de que se realiza el análisis de opción, 'ARGV' contiene solo los operandos, si los hay (es decir, los argumentos restantes, NO-opción). – mklement0

23

Desafortunadamente, Ruby no es compatible con un mecanismo de paso como, por ejemplo, AWK:

> awk -v a=1 'BEGIN {print a}' 
> 1 

Significa que no puede pasar valores con nombre directamente a su secuencia de comandos.

Utilización de opciones de CMD pueden ayudar:

> ruby script.rb val_0 val_1 val_2 

# script.rb 
puts ARGV[0] # => val_0 
puts ARGV[1] # => val_1 
puts ARGV[2] # => val_2 

tiendas de Ruby todos los argumentos CMD en el array ARGV, la scriptname sí mismo puede ser capturado utilizando la variable $PROGRAM_NAME.

La desventaja obvia es que depende del orden de los valores.

Si necesita sólo interruptores booleanas utilizan la opción -s del intérprete Ruby:

> ruby -s -e 'puts "So do I!" if $agreed' -- -agreed 
> So do I! 

Tenga en cuenta el interruptor --, de lo contrario Rubí se quejará de una opción inexistente -agreed, por lo que pasarlo como un interruptor a su cmd invocacionUsted no lo necesita en el siguiente caso:

> ruby -s script_with_switches.rb -agreed 
> So do I! 

La desventaja es que meterse con las variables globales y tienen valores de verdadero/falso lógico.

Se puede acceder a los valores de las variables de entorno:

> FIRST_NAME='Andy Warhol' ruby -e 'puts ENV["FIRST_NAME"]' 
> Andy Warhol 

Los inconvenientes están presentes aquí para, usted tiene que fijar todas las variables antes de la invocación de la escritura (sólo para el proceso de rubí) o para exportarlos (conchas como BASH):

> export FIRST_NAME='Andy Warhol' 
> ruby -e 'puts ENV["FIRST_NAME"]' 

en este último caso, sus datos serán legibles para todos en la misma sesión de shell y para todos los subprocesos, que pueden ser una consecuencia grave de seguridad.

Y al menos puede implementar un analizador de opciones usando getoptlong y optparse.

Happy hacking!

1

También puede probar cliqr. Es bastante nuevo y en desarrollo activo. Pero hay versiones estables listas para ser usadas. Aquí está el repo de git: https://github.com/anshulverma/cliqr

Mire en la carpeta de ejemplos para tener una idea de cómo se puede utilizar.

1

Ejecutar este código en la línea de comandos y escriba el valor de N:

N = gets; 1.step(N.to_i, 1) { |i| print "hello world\n" } 
Cuestiones relacionadas