2010-11-22 152 views
207

我已經在Windows上安裝了RubyInstaller,並且正在運行IMAP Sync,但我需要使用它來同步數百個帳戶。如果我可以通過命令行將這些變量傳遞給它,我可以更好地自動化整個過程。通過命令行將變量傳遞給Ruby腳本

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

回答

368

事情是這樣的:

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 
+62

我想明確指出,ARGV [0]不指向程序名,因爲一些其他語言做。要獲取程序名稱,請參閱http://stackoverflow.com/questions/4834821/how-can-i-get-the-name-of-the-command-called-for-usage-prompts-in-ruby – 2015-05-01 18:37:47

161

不要推倒重來;檢查Ruby的方式 - 酷的OptionParser庫。

它提供標記/開關解析,帶有可選或必需值的參數,可將參數列表解析爲單個選項,並可爲您生成幫助。此外,如果您傳遞的任何信息都非常靜態,即不會在運行之間更改,請將其放入一個經過分析的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: [email protected] 
dest_host: imap.gmail.com 
dest_port: 993 
dest_ssl: true 
dest_user: [email protected] 
dest_pass: password 

這將讓你輕鬆地生成一個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鏈接已死亡。嘗試http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html – Casey 2012-08-23 17:55:06

+6

優秀的答案;可能值得補充的是,在完成選項分析後,「ARGV」只包含操作數(如果有的話)(即剩餘的非選項參數)。 – mklement0 2015-07-13 22:07:40

23

不幸的是,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 

紅寶石存儲所有CMD參數的ARGV數組中的腳本名稱本身可以使用$PROGRAM_NAME變量被捕獲。

明顯的缺點是您依賴於值的順序。

如果您只需要布爾交換機使用Ruby解釋器的選項-s

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

請注意--開關,否則紅寶石會抱怨不存在的選項-agreed,所以把它作爲一個切換到您的cmd調用。在以下情況下,您不需要它:

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

缺點是您會混淆全局變量並且只有邏輯真/假值。

您可以從環境變量訪問值:

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

在後一種情況下,你的數據將是可讀的每個人都在同一個shell會話和所有子過程,它可以是一個嚴重的安全含義。

至少您可以使用getoptlongoptparse來實現選項解析器。

快樂黑客!

1

運行在命令行上的代碼,輸入N的值:

N = gets; 1.step(N.to_i, 1) { |i| print "hello world\n" } 
相關問題