命令行参数

“从命令行开始”。不管Ruby用在哪个系统上,无论是超级的科学工作站或者是嵌入式PDA设备,你无论如何都要从Ruby的解释器开始,这会给我们传递命令行参数的机会。

Ruby的命令行由三个部分组成:Ruby解释器选项,可选的要运行程序的名字,和可选的用于那个程序的一组参数。

ruby [ options ] [ -- ] [ programfile ] [ arguments ]

Ruby选项是命令行直接跟在第一个单词后面的,它不能用连字号,或特殊标志--(两个连字号)开头。

如果命令行上未出现文件名,或如果文件名是单个连字号(-),Ruby从标准输入中读取程序源代码。

传递给程序本身的参数跟随在程序名字的后面。例如:

% ruby -w - "Hello World"

打开警告,从标准输入读取程序,并传递双引号字符串"Hello World"做为参数。

 

命令行选项

-0[octal] 0标志(数字零)指定记录的分隔字符(,如果没有数字跟随)。-00指出段落模式:记录由两个连续的缺省记录分隔字符分隔。-0777一次读入整个文件(它像个非法字符)。设置$/。

-a 当使用-n或-p时的自动分离模式,等价于在每个循环迭代器上执行$F = $_.split。

-C directory 在运行之前修改工作路径。

-c 只检查符号,不运行程序。

-copyright 打印版权信息并退出。

-d, -debug 设置 $DEBUG 和 $VERBOSE 为 true。这可以用于你的程序的额外追踪。

-e 'command' 执行做为一行Ruby源码的命令。允许几个-e,在同一程序中命令被视做多行。当-e出现时,如果程序文件被忽略,在-e命令被运行完后中止运行。程序运行时使用-e可访问旧的条件中的范围和正则表达式的行为-整数范围比较当前输入行号,正式表达式匹配$_。

-F pattern 指定用于split()的缺省输入字段分隔符($;)(影响-a选项)。

-h, -help 显示一个简短的帮助屏幕。

-I directories 指定预定义的$LOAD_PATH($:)指令。可以有多个-I选项。每个-I后可有多个用冒号:分隔的指令。在类Unix系统上是分号(;)。

-i[extension] 以替换形式编辑ARGV文件。ARGV内的每个文件名,你写入到标准输出的任何东西,都将被回储到那个文件的内容中。如果有扩展名的话,备份文件会被保留下来。

% ruby -pi. bak –e "gsub(/Perl/, 'Ruby')" *.txt

-K kcode 指定要使用的编码。当Ruby使用日语时这个选项很有用。Kcode可以是这些当中的一个: e, E for EUC; s, S 对应 SJIS; u, U 对应 UTF-8; or a, A, n, N 对应 ASCII.

-l 自动进行行尾处理;设置$的值为$/,并且对读入的行自动地进行String#chop!处理。

-n Assumes a while gets; ...; end loop around your program. For example, a simple grep command could be implemented as

% ruby –n –e "print if /wombat/" *.txt

-p Places your program code within the loop while gets; ...; print; end.

% ruby –p –e "$_.downcase!" *.txt

-r library 在运行前请求给出名字的库。

-S 查看程序文件是否使用了RUBYPATH或PATH环境变量。

-s Any command-line switches found after the program filename, but before any filename arguments or before a , are removed from ARGV and set to a global variable named for the switch. In the following example, the effect of this would be to set the variable $opt to "electric".

% ruby -s prog -opt= electric ./mydata

-T[level] 设置安全级别,执行不纯度测试(见379页)。设置$SAFE。

-v, -verbose 设置$VERBOSE为true,打开冗长模式。也打印版本号。在冗长模式中,可打印编译警告。如果命令行上没有指定文件名,则Ruby退出。

--version 显示Ruby的版本信息并退出。

-w 打开冗长模式。与-v不同,如果命令行上没有指定文件名则从标准输入读入程序。我们推荐带 –w 来运行你程序。

-W level 设置警告的级别。可有一个或两个级别(或者没指定级别),等价于-w—给出额外的警告。如果级别为1,运行在标准(缺省)警告级别上。使用-W0则不显示警告(包括使用Kernel.warn的警告)。

-X directory 在运行前更改工作目录。类似于-c directory 。

-x [directory] 从#!Ruby行取出文本,如果指定目录的话,并且要修改工作目录。

-y, -yydebug 在解析器中打开yacc调试器。

 

ARGV

程序名字后面的任何命令行参数都会对你的程序打开全局数组ARGV。例如,假设test.rb包含了下面程序:

ARGV.each {|arg| p arg }

用下同命令行调用它:

% ruby –w test.rb "Hello World" a1 1.6180

会产生如下输出:

"Hello World"

"a1"

"1.6180"

这是给C程序员准备的—ARGV[0]是传递给程序的第一个参数,不是程序的名字。当前程序的名字是全局变量$0中的变量。注意ARGV的所有值都是字符串。

如果你的程序试图从标准输入来读(或使用特殊文件ARGF,它 321页描述),ARGV内的程序参数将接受文件名,并且Ruby会从这些文件中读入。如果你程序带有混合参数和文件名,确信你在从文件读之前倾空了ARGV数组。

 

程序中止

方法Kernel#exit中止你的程序,并向操作系统返回一个状态值。虽然,不像一些语言,exit不立即中止程序。Kernel#exit首先引发一个SystemExit异常,你可以捕获它,然后程序执行一系列清除动作,包括运行所有的注册的at_exit方法和对象的finalizer。参考500页的Kernel#exit描述。

 

环境变量

你可以使用预定义的变量ENV来访问操作系统环境变量。它像哈希表一样响应一些方法。[ENV其实不是哈希表,但如果你需要的话,你可以使用ENV#to_hash,来把它转换到成哈希表]。

ENV['SHELL'] => "/bin/sh"

ENV['HOME'] => "/Users/dave"

ENV['USER'] => "dave"

ENV.keys.size => 34

ENV.keys[0, 7] => ["MANPATH", "TERM_PROGRAM", "TERM", "SHELL",

"SAVEHIST", "HISTSIZE", "MAKEFLAGS"]

当Ruby首次启动时要读取一些环境变量值。这些变量修改解释程序的行为,像表14.1中显示的。

Table 14.1. Ruby使用的环境变量
 
变量名称
 描述
 
DLN_LIBRARY_PATH
 用于搜索被动态加载的模块的路径。
 
HOME
 指向用户的主目录。
 
LOGDIR
 Fallback pointer to the user’s home directory if $HOME is not set. Used only by Dir.chdir.
 
OPENSSL_CONF
 指定OpenSSL的本地配置文件。
 
RUBYLIB
 为Ruby程序添加搜索路径($SAFE 必须被设置成)。
 
RUBYLIB_PREFIX (Windows only)
 Mangle the RUBYLIB search path by adding this prefix to each component.
 
RUBYOPT
 给Ruby添加命令行选项,在命令行选项并解析后进行检查($SAFE 必须设置成0)。
 
RUBYPATH
 指定–S选项,Ruby会搜索路径(缺省值是PATH)。
 
RUBYSHELL
 Shell to use when spawning a process under Windows; if not set, will also check SHELL or COMSPEC.
 
RUBY_TCL_DLL
 Override default name for TCL shared library or DLL.
 
RUBY_TK_DLL
 Override default name for Tk shared library or DLL. Both this and RUBY_TCL_DLL must be set for either to be used.
 

 

写入环境变量

Ruby程序可以对ENV对象进行写操作。在大多数系统上这会修改相应的环境变量的值。虽然,这种修改是本地的,只针对于这个进程或其随后的子进程。环境变量的种继承在下面例子中说明。一个子进程若修改了一个环境变量,这个修改会被一个进程继承然后启动。尽管修改对原有的父进程不可见。(这只是证明了它的父进程并不真的知道子进程再做什么。)

puts "In parent, term = #{ENV['TERM']}"

fork do

puts "Start of child 1, term = #{ENV['TERM']}"

ENV['TERM'] = "ansi"

fork do

puts "Start of child 2, term = #{ENV['TERM']}"

end

Process.wait

puts "End of child 1, term = #{ENV['TERM']}"

end

Process.wait

puts "Back in parent, term = #{ENV['TERM']}"

produces:

In parent, term = xtermcolor

Start of child 1, term = xtermcolor

Start of child 2, term = ansi

End of child 1, term = ansi

Back in parent, term = xtermcolor

 

Ruby在哪里找到它的模块

你使用require或load来使库模块添加到你的Ruby程序内。这些模块中一些应用于Ruby,一些你可以安装Ruby的应用程序文档(RAA),一些是你自己写。Ruby是如何找到它们呢?

当Ruby构建你的特殊机器时,它会预先确定持有库资料的标准目录。这些依赖于机器。你可以像这样在命令行中确定它们

% ruby –e 'puts $:'

在典型的Linux box 上,你或许会找到一些如下面显示的。注意Ruby1.8中,这些目录的次序已被修改—下面目录依赖于它们的机器。

/usr/local/lib/ruby/site_ruby/1.8

/usr/local/lib/ruby/site_ruby/1.8/i686linux

/usr/local/lib/ruby/site_ruby

/usr/local/lib/ruby/1.8

/usr/local/lib/ruby/1.8/i686linux

site_ruby目录持有模块和你添加扩展的模块。依赖于系统的目录(本例中是i686-linux)持有可运行的和其它指定给此机器的。所有这些目录被自动地包含在Ruby对模块的搜索路径内。