310 votes

Passer des variables au script Ruby via la ligne de commande

J'ai installé RubyInstaller sous Windows et j'exécute Synchronisation IMAP mais j'ai besoin de l'utiliser pour synchroniser des centaines de comptes. Si je pouvais lui passer ces variables via la ligne de commande, je pourrais mieux automatiser l'ensemble du processus.

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

# Destination server connection info.
DEST_NAME = 'username@gmail.com'
DEST_HOST = 'imap.gmail.com'
DEST_PORT = 993
DEST_SSL  = true
DEST_USER = 'username@gmail.com'
DEST_PASS = 'password'

2 votes

Vous pouvez envisager d'éditer cette question populaire en un véritable question .

518voto

demas Points 10567

Quelque chose comme ça :

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

puis

$ ./test.rb "test1 test2"

o

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

94 votes

Je tiens à signaler explicitement que ARGV[0] ne pointe pas vers le nom du programme, comme le font certains autres langages. Pour obtenir le nom du programme, voir stackoverflow.com/questions/4834821/

8 votes

Est-ce que "test1 test2" n'est pas un seul argument ?

2 votes

Vous devez ajouter #!/usr/bin/env ruby sur le dessus de .rb pour pouvoir l'exécuter comme ceci : ./test.rb

208voto

the Tin Man Points 69148

Ne réinventez pas la roue, jetez un coup d'œil à la solution très cool de Ruby. OptionParser bibliothèque.

Il permet d'analyser les drapeaux/interrupteurs, les paramètres avec des valeurs optionnelles ou obligatoires, peut analyser des listes de paramètres en une seule option et peut générer votre aide pour vous.

De même, si l'une des informations transmises est plutôt statique et ne change pas d'une exécution à l'autre, placez-la dans un fichier YAML qui sera analysé. De cette façon, vous pouvez avoir des choses qui changent à chaque fois sur la ligne de commande, et des choses qui changent occasionnellement configurées en dehors de votre code. Cette séparation des données et du code est intéressante pour la maintenance.

Voici quelques échantillons avec lesquels vous pouvez jouer :

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']

Il s'agit d'un exemple de fichier YAML si vos destinations sont plutôt statiques :

--- 
dest_name: username@gmail.com
dest_host: imap.gmail.com
dest_port: 993
dest_ssl: true
dest_user: username@gmail.com
dest_pass: password

Cela vous permettra de générer facilement un fichier YAML :

require 'yaml'

yaml = {
  'dest_name' => 'username@gmail.com',
  'dest_host' => 'imap.gmail.com',
  'dest_port' => 993,
  'dest_ssl'  => true,
  'dest_user' => 'username@gmail.com',
  'dest_pass' => 'password'
}

puts YAML.dump(yaml)

2 votes

Le lien vers OptParse est mort. Essayez ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/

7 votes

Excellente réponse ; cela peut valoir la peine d'ajouter cela après que l'analyse des options soit faite, ARGV ne contient que les opérandes, s'il y en a (c'est-à-dire les arguments restants, sans option).

30voto

Andrei Beliankou Points 149

Malheureusement, Ruby ne supporte pas un tel mécanisme de passage comme par exemple AWK :

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

Cela signifie que vous ne pouvez pas passer des valeurs nommées dans votre script directement.

L'utilisation des options cmd peut aider :

> 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

Ruby stocke tous les arguments cmd dans le fichier ARGV le nom de script lui-même peut être capturé à l'aide de la fonction $PROGRAM_NAME variable.

L'inconvénient évident est que vous dépendez de l'ordre des valeurs.

Si vous n'avez besoin que de commutateurs booléens, utilisez l'option -s de l'interpréteur Ruby :

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

Veuillez noter que le -- sinon Ruby se plaindra d'une option inexistante. -agreed Il faut donc le passer en tant que commutateur à votre invocation cmd. Vous n'en avez pas besoin dans le cas suivant :

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

L'inconvénient, c'est que vous vous embrouillez avec les variables globales et que vous n'avez que des valeurs logiques vrai/faux.

Vous pouvez accéder aux valeurs des variables d'environnement :

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

Les inconvénients sont présents ici aussi, vous devez définir toutes les variables avant l'invocation de script (seulement pour votre processus ruby) ou les exporter (shells comme BASH) :

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

Dans ce dernier cas, vos données seront lisibles par tous les participants à la même session du shell et par tous les sous-processus, ce qui peut avoir de graves conséquences sur la sécurité.

Et au moins vous pouvez implémenter un analyseur d'options en utilisant getoptlong y optparse .

Bon piratage !

3voto

Redithion Points 634

Tl;dr

Je sais que c'est vieux, mais getoptlong n'a pas été mentionné ici et c'est probablement la meilleure façon d'analyser les arguments de ligne de commande aujourd'hui.


Analyse des arguments de la ligne de commande

Je recommande vivement getoptlong . Il est assez facile à utiliser et fonctionne comme un charme. Voici un exemple extrait du lien ci-dessus

require 'getoptlong'

opts = GetoptLong.new(
    [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
    [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],
    [ '--name', GetoptLong::OPTIONAL_ARGUMENT ]
)

dir = nil
name = nil
repetitions = 1
opts.each do |opt, arg|
    case opt
        when '--help'
            puts <<-EOF
hello [OPTION] ... DIR

-h, --help:
     show help

--repeat x, -n x:
     repeat x times

--name [name]:
     greet user by name, if name not supplied default is John

DIR: The directory in which to issue the greeting.
            EOF
        when '--repeat'
            repetitions = arg.to_i
        when '--name'
            if arg == ''
                name = 'John'
            else
                name = arg
            end
    end
end

if ARGV.length != 1
    puts "Missing dir argument (try --help)"
    exit 0
end

dir = ARGV.shift

Dir.chdir(dir)
for i in (1..repetitions)
    print "Hello"
    if name
        print ", #{name}"
    end
    puts
end

Vous pouvez l'appeler comme ceci ruby hello.rb -n 6 --name -- /tmp

Ce que le PO essaie de faire

Dans ce cas, je pense que la meilleure option est d'utiliser les fichiers YAML comme suggéré. dans cette réponse

1voto

nuaavee Points 360

Vous pouvez également essayer cliqr . Il est assez nouveau et en développement actif. Mais il existe des versions stables prêtes à être utilisées. Voici le dépôt git : https://github.com/anshulverma/cliqr

Consultez le dossier d'exemples pour vous faire une idée de la façon dont il peut être utilisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X