Передача переменных в скрипт Ruby через командную строку - PullRequest
260 голосов
/ 22 ноября 2010

Я установил RubyInstaller в Windows и использую IMAP Sync , но мне нужно использовать его для синхронизации сотен учетных записей.Если бы я мог передать эти переменные ему через командную строку, я бы лучше автоматизировал весь процесс.

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

Ответы [ 7 ]

443 голосов
/ 22 ноября 2010

Примерно так:

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

тогда

$ ./test.rb "test1 test2"

или

v1 = ARGV[0]
v2 = ARGV[1]
puts v1       #prints test1
puts v2       #prints test2
182 голосов
/ 22 ноября 2010

Не изобретай велосипед;проверьте Ruby's way-cool OptionParser library.

Он предлагает анализ флагов / переключателей, параметров с необязательными или обязательными значениями, может анализировать списки параметров в одну опцию и может генерировать вашу помощьдля вас.

Кроме того, если передаваемая вами информация довольно статична и не меняется между запусками, поместите ее в YAML-файл, который будет проанализирован.Таким образом, вы можете иметь вещи, которые меняются каждый раз в командной строке, и вещи, которые изменяются, иногда настраиваемые вне вашего кода.Такое разделение данных и кода удобно для обслуживания.

Вот несколько примеров, с которыми можно поиграть:

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

Это пример файла 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

Это позволит вам легко сгенерировать файл 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)
26 голосов
/ 07 ноября 2012

К сожалению, Ruby не поддерживает такой механизм передачи, как, например, AWK:

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

Это означает, что вы не можете напрямую передавать именованные значения в ваш скрипт.

Использование параметров cmd может помочь:

> 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 сохраняет все аргументы cmd в массиве ARGV, само имя сценария может быть записано с помощью переменной $PROGRAM_NAME.

Очевидным недостатком является то, что вы зависите от порядказначения.

Если вам нужны только логические ключи, используйте параметр -s интерпретатора Ruby:

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

Обратите внимание на переключатель --, в противном случае Ruby будет жаловаться на несуществующий параметр-agreed, поэтому передайте его как переключатель для вызова cmd.Вам не нужно это в следующем случае:

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

Недостатком является то, что вы связываетесь с глобальными переменными и имеете только логические значения true / false.

Вы можете получить доступ к значениям из средыпеременные:

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

Здесь присутствуют недостатки, вы должны установить все переменные перед вызовом скрипта (только для вашего процесса ruby) или экспортировать их (оболочки типа BASH):

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

В последнем случае ваши данные будут доступны для чтения для всех в одном сеансе оболочки и для всех подпроцессов, что может стать серьезным следствием для безопасности.

И, по крайней мере, вы можете реализовать анализатор параметров, используя getoptlong и optparse .

Счастливого взлома!

1 голос
/ 06 апреля 2018

Если это не самый тривиальный случай, есть только один разумный способ использовать параметры командной строки в Ruby.Он называется docopt и задокументирован здесь .

Что удивительно в этом, так это простота. Все, что вам нужно сделать, это указать текст «справки» для вашей команды. То, что вы там напишите, будет автоматически проанализировано автономной (!) Библиотекой ruby.

Из примера :

#!/usr/bin/env ruby
require 'docopt.rb'

doc = <<DOCOPT
Usage: #{__FILE__} --help
       #{__FILE__} -v...
       #{__FILE__} go [go]
       #{__FILE__} (--path=<path>)...
       #{__FILE__} <file> <file>

Try: #{__FILE__} -vvvvvvvvvv
     #{__FILE__} go go
     #{__FILE__} --path ./here --path ./there
     #{__FILE__} this.txt that.txt

DOCOPT

begin
  require "pp"
  pp Docopt::docopt(doc)
rescue Docopt::Exit => e
  puts e.message
end

Выход:

$ ./counted_example.rb -h
Usage: ./counted_example.rb --help
       ./counted_example.rb -v...
       ./counted_example.rb go [go]
       ./counted_example.rb (--path=<path>)...
       ./counted_example.rb <file> <file>

Try: ./counted_example.rb -vvvvvvvvvv
     ./counted_example.rb go go
     ./counted_example.rb --path ./here --path ./there
     ./counted_example.rb this.txt that.txt

$ ./counted_example.rb something else
{"--help"=>false,
 "-v"=>0,
 "go"=>0,
 "--path"=>[],
 "<file>"=>["something", "else"]}

$ ./counted_example.rb -v
{"--help"=>false, "-v"=>1, "go"=>0, "--path"=>[], "<file>"=>[]}

$ ./counted_example.rb go go
{"--help"=>false, "-v"=>0, "go"=>2, "--path"=>[], "<file>"=>[]}

Наслаждайтесь!

1 голос
/ 06 августа 2015

Запустите этот код в командной строке и введите значение N:

N  = gets; 1.step(N.to_i, 1) { |i| print "hello world\n" }
1 голос
/ 18 июня 2015

Вы также можете попробовать cliqr.Это довольно новый и в активном развитии.Но есть стабильные релизы, готовые к использованию.Вот репозиторий git: https://github.com/anshulverma/cliqr

Просмотрите папку с примером, чтобы получить представление о том, как ее можно использовать.

0 голосов
/ 16 апреля 2019

Вы должны попробовать console_runner gem.Этот гем делает ваш чистый код Ruby исполняемым из командной строки.Все, что вам нужно, это добавить YARD аннотации к вашему коду:

# @runnable This tool can talk to you. Run it when you are lonely.
#   Written in Ruby.  
class MyClass

    def initialize
      @hello_msg = 'Hello' 
      @bye_msg = 'Good Bye' 
    end

    # @runnable Say 'Hello' to you.
    # @param [String] name Your name
    # @param [Hash] options options
    # @option options [Boolean] :second_meet Have you met before?
    # @option options [String] :prefix Your custom prefix
    def say_hello(name, options = {})
      second_meet = nil
      second_meet = 'Nice to see you again!' if options['second_meet']
      prefix = options['prefix']
      message = @hello_msg + ', '
      message += "#{prefix} " if prefix
      message += "#{name}. "
      message += second_meet if second_meet
      puts message
    end

end

Затем запустить его из консоли:

$ c_run /projects/example/my_class.rb  say_hello -n John --second-meet --prefix Mr. 
-> Hello, Mr. John. Nice to see you again!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...