使用Ruby编写脚本进行系统管理的教程
简介
Ruby是一种功能极其丰富的、免费的、简单的、可扩展的、可移植的、面向对象的脚本编程语言。最近,它在Web领域广受欢迎。这在一定程度上要归因于非常强大的Web应用程序开发框架Rails,Rails正是用Ruby编写的。Rails,也称RubyonRails(ROR),顾名思义,它为快速、有效地开发Web应用程序提供一个非常强大的平台。它是高度可伸缩的,Web上有很多站点就是用RubyonRails构建的。
除了与Rails一起用作Web应用程序开发平台外,Ruby还具有较少被提及的另一面,那就是作为一种强大的脚本编程语言,就像Python或Perl那样。它拥有非常强大的功能,由于可以使用很多内建的和外部的库,因此可利用它的威力来解决通常系统管理工作环境中出现的很多脚本编程需求。
系统管理需要大量编写脚本以使事情更简单、更有效。编写脚本比单调的手动工作能更好地解决用户管理、进程管理、文件管理、软件包管理和其他基本的自动化需求。在这个场景中,Ruby非常有用。它有一套很好的库可满足这一点。
对于本文,我假设读者具有Ruby的应用知识。这里提供的基本例子使用纯Ruby,因此可以在Ruby支持的任何类UNIX?系统以及Windows?上运行。对于更高级的Cfruby例子,需要能够使用一个UNIX系统。下面所有的例子已经在一台Linux?机器上使用Rubyv1.8.4进行了测试。它们应该也能用于最新版本的Ruby。
实践中的Ruby
第一个例子在指定路径中搜索符合给定模式的文件,并以用户友好的方式给出关于这些文件的详细信息。实现这一目标不必依赖于任何命令行实用程序,只需使用Ruby内建的API。因此,这个例子在有Ruby运行的任何平台上都能运行。
而且,这个例子展示了Ruby在简化脚本编写需求方面有多强大。它不是简单地模拟*nix"find"命令,而是构建在该命令之上,因而在使用Ruby时具有很强的定制能力。
清单1.在给定路径中搜索符合给定模式的模式的文件,并显示它们的详细信息
require'find' puts"" puts"-----------------------FileSearch-----------------------------------" puts"" print"Enterthesearchpath:" searchpath=gets searchpath=searchpath.chomp puts"" print"Enterthesearchpattern:" pattern=gets pattern=pattern.chomp puts"----------------------------------------------------------------------" puts"Searchingin"+searchpath+"forfilesmatchingpattern"+pattern puts"----------------------------------------------------------------------" puts"" Find.find(searchpath)do|path| ifFileTest.directory?(path) ifFile.basename(path)[0]==?. Find.prune#Don'tlookanyfurtherintothisdirectory. else next end else ifFile.fnmatch(pattern,File.basename(path)) puts"Filename:"+File.basename(path) s=sprintf("%o",File.stat(path).mode) print"Permissions:" putss print"Owninguid:" putsFile.stat(path).uid print"Owninggid:" putsFile.stat(path).uid print"Size(bytes):" putsFile.stat(path).size puts"---------------------------------------------------" end end end
在这个例子中:
- 第5-11行-请求用户提供搜索路径和搜索模式。
- 第16行-使用Ruby中“Find”类中的“find”方法遍历指定的搜索路径。
- 第17行-检查发现的文件是否为一个目录。如果是目录,并且不是“.”,则递归地遍历该目录。
- 第24行-使用“File”类中的“fnmatch”方法检查发现的文件是否符合给定的模式。
- 第25-34行-如果文件符合模式,则打印文件的详细信息。
下面是这个脚本的一个示例输出。
清单2.第一个例子的示例输出
[root@logan]#rubyfindexample.rb -----------------------FileSearch----------------------------------- Enterthesearchpath:/test Enterthesearchpattern:*.rb ---------------------------------------------------------------------- Searchingin/testforfilesmatchingpattern*.rb ---------------------------------------------------------------------- Filename:s.rb Permissions:100644 Owninguid:1 Owninggid:1 Size(bytes):57 --------------------------------------------------- Filename:test.rb Permissions:100644 Owninguid:0 Owninggid:0 Size(bytes):996 --------------------------------------------------- Filename:s1.rb Permissions:100644 Owninguid:1 Owninggid:1 Size(bytes):39 ---------------------------------------------------
在系统管理期间,最常见的一个需求是有效地使用zip文件来管理备份,或者将一组文件从一台计算机转移到另一台计算机。在这个方面,Ruby很有优势。这里的第二个例子构建在第一个例子的基础上,但是包含了一个场景,在此场景中,需要将搜索到的文件打包到zip文件中。
内建的zlib模块可帮助处理gzip文件,对于大多数情况它都够好。但是,在这里我将使用另一个很好的Ruby库,即“rubyzip”,来创建和处理zip归档文件。请查看参考资料小节,找到下载它的链接。而且要注意,这个例子使用纯Ruby,它不依赖于计算机上当前提供的任何命令行实用程序。
安装rubyzip
通过提供的链接下载“rubyzip”gem,并将它复制到系统中。(在撰写本文之际,它的文件名是“rubyzip-0.9.1.gem”)。
运行gem安装rubyzip-0.9.1.gem
清单3.使用zip文件
require'rubygems' require_gem'rubyzip' require'find' require'zip/zip' puts"" puts"------------------FileSearchandZip-----------------------------" puts"" print"Enterthesearchpath:" searchpath=gets searchpath=searchpath.chomp puts"" print"Enterthesearchpattern:" pattern=gets pattern=pattern.chomp puts"----------------------------------------------------------------------" puts"Searchingin"+searchpath+"forfilesmatchingpattern"+pattern puts"----------------------------------------------------------------------" puts"" puts"----------------------------------------------------------------------" puts"Zippingupthefoundfiles..." puts"----------------------------------------------------------------------" Zip::ZipFile.open("test.zip",Zip::ZipFile::CREATE){ |zipfile| Find.find(searchpath)do|path| ifFileTest.directory?(path) ifFile.basename(path)[0]==?. Find.prune#Don'tlookanyfurtherintothisdirectory. else next end else ifFile.fnmatch(pattern,File.basename(path)) pFile.basename(path) zipfile.add(File.basename(path),path) end end end }
这个脚本为根据提供的搜索路径和搜索模式搜索到的文件创建一个名为“test.zip”的zip文件。
这个例子做以下事情:
- 第9-15行-请求用户提供搜索路径和搜索模式。
- 第23行-创建一个新的名为“test.zip”的ZipFile。
- 第25行-使用Ruby中“Find”类中的“find”方法遍历指定的搜索路径。
- 第26行-检查发现的文件是否为一个目录。如果是目录,并且不是“.”,则递归地遍历该目录。
- 第33行-使用“File”类中的“fnmatch”方法检查发现的文件是否符合给定的模式。
- 第35行-将符合的文件添加到zip归档中。
下面是一个示例输出:
清单4.第二个例子的示例输出
[root@logan]#rubyzipexample.rb -----------------------FileSearch----------------------------------- Enterthesearchpath:/test Enterthesearchpattern:*.rb ---------------------------------------------------------------------- Searchingin/testforfilesmatchingpattern*.rb ---------------------------------------------------------------------- ---------------------------------------------------------------------- Zippingupthefoundfiles... ---------------------------------------------------------------------- "s.rb" "test.rb" "s1.rb" [root@logan]#unzip-ltest.zip Archive:test.zip LengthDateTimeName -------------------- 99609-25-0821:01test.rb 5709-25-0821:01s.rb 3909-25-0821:01s1.rb --------------- 10923files
Cfruby-高级的系统管理
根据Cfruby站点的定义,“Cfruby允许使用Ruby进行系统管理。它既是一个用于系统管理的Ruby函数库,又是一个类Cfengine的克隆品(实际上是用于系统管理的一种特定领域语言,即DSL)”。
Cfruby基本上是一个由两部分组成的包:
- Cfrubylib–一个纯Ruby库,其中包含用于系统管理的类和方法。这包括文件复制、查找、校验和检查、包管理、用户管理等。
- Cfenjin–一种简单的脚本编程语言,可帮助为系统管理任务编写脚本(不必知道Ruby)。
Cfruby可以作为一个Rubygem或tar压缩文件下载。gem是最简单、最容易的方式。获取gem,并使用“geminstall”命令安装它。
安装Cfruby:
- 将下载的Cfrubygem文件复制到系统中。(在撰写本文之际,它的文件名是“cfruby-1.01.gem”)。
- 运行gem安装cfruby-1.01.gem。
Cfruby现在应该被安装到系统上。
使用Cfruby
现在,我将展示Cfruby的功能,以及它如何大大简化系统管理。
有两种基本的方式可访问Cfruby库提供的功能:
- 直接使用libcfgruby中的Ruby类。
- 使用cfrubyscript包装器,它为libcfruby提供了一个更简洁的接口。
直接使用libcfruby中的Ruby类
Libcfruby是Cfruby的核心,它包含一组模块,这些模块提供了各种用于简化系统维护和设置的功能。为了使用libcfruby,需要在安装Cfrubygem之后,将“require_gem'cfruby'”添加到脚本的顶端。这样便可以直接访问libcfruby中的所有核心模块,在脚本中可以根据需要按任意方式使用它们。这种方法惟一的缺点是libcfruby比较大,它将所有的类和方法都放入到它们各自的名称空间中。所以,为了访问任何一个类,都需要以名称空间加以限定。例如,libcfruby提供了一个用于获得系统类型的方法。要获取操作系统的类型,需要做以下事情:
清单5.使用libcfruby获取操作系统类型
require'rubygems' require_gem'cfruby' os=Cfruby::OS::OSFactory.new.get_os() puts(os.name)
这只是获得操作系统的名称。随着您用libcfruby做更多的事情,您的脚本中将充斥着更多指定名称空间的语句。正是由于这一点,另一种使用Cfruby的方法就显得很方便。
使用cfrubyscript包装器,这个包装器为libcfruby提供了一个更简洁的接口
为了使用cfrubyscript包装器,需要添加:
清单6.使用cfrubyscript
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript'
这样会将cfrubyscript包括到脚本中,然后就可以通过一个更简单的接口来访问libcfruby的功能。
cfrubyscript做到了以下几点:
- 它将一组变量导出到全局名称空间,例如$os、$pkg、$user、$proc和$sched。
- 它将大多数主要模块放到主名称空间中,所以可以调用FileEdit.set而不是Cfruby::FileEdit.set。
- 它为String和Array添加了很多助手方法,这些方法可以做一些Cfruby事情(安装程序、编辑文件等)。
- 它还提供了一个很好的日志记录器。
所以,不再需要在脚本中指定一大堆的名称空间。上面用于获取操作系统类型的例子现在变成这样:
清单7.使用cfrubyscript获取操作系统的类型
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript' puts($os.name)
这可以翻译成一个单独的调用,该调用使用全局变量$os。Cfruby的确强大,它为管理类*nix系统提供了很多功能。
现在来看看其中一些功能,以及使用它们的一些基本例子。
用户管理
在系统管理中,最常见、最重要的任务之一就是用户和组的管理。Cfruby以一种可移植的、简单的方式提供了一套强大的方法来实现该任务。
该任务是使用UserManager对象实现的,这个对象可以像下面这样从OS模块获得。
清单8.使用libcfruby获得UserManager对象
require'rubygems' require_gem'cfruby' osfactory=Cfruby::OS::OSFactory.new() os=osfactory.get_os() usermgr=os.get_user_manager()
如果使用cfrubyscript方式,那么已经有一个全局用户管理对象,即$user,它可以直接用于调用方法。我将使用这种方法,因为这样更简单,更易于阅读。
下面展示如何使用它来创建和删除一个用户。
清单9.使用cfgrubyscript进行用户管理
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript' $user.adduser('newusername','password') $user.deleteuser('usernametodelete',true)
上述代码做什么事情?
- 第1、2行–和通常一样,将libcfruby和cfrubyscript包括到脚本中。
- 第3行–以用户名“newusername”和第二个参数指定的密码创建一个新用户。
- 第4行–删除用户名为“usernametodelete”的用户。第二个参数的值可以是true或false,用于指定是否删除被删除用户的主目录。
类似地,组操作也可以使用UserManager对象中的addgroup()和deletegroup()方法来完成。
进程管理
管理员的另一项重要的任务是跟踪系统上运行的进程,并管理它们。Cfruby在这方面也很有用,它为有效地处理进程提供了方法。
您可以使用Cfruby实现它。
清单10.使用cfgrubyscript进行进程管理
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript' $proc.kill($proc.vim) 'ps–aef'.exec()
上述代码做什么事情?
- 第3行–使用全局ProcessManager对象$proc关闭由参数指定的“vim”进程。$proc.vim是在系统上运行的“vim”进程的一个ProcessInfo类型的对象。它们是由cfrubyscript自动创建的。
- 第4行–用指定的命令“ps–aef”启动一个新进程。可以从命令字符串中直接调用exec方法。
包管理
系统管理员必须负责的另一项任务是管理系统上的包。Cfruby提供了一些方法用于方便地在系统上安装和删除软件。
清单11.使用cfgrubyscript进行包管理
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript' all=$pkg.packages() installed=$pkg.installed_packages() ruby.install()
上述代码做什么事情?
- 第3行–使用cfrubyscript创建的全局$pkgPackageManager对象,通过调用packages()方法获得系统上所有可用的包。
- 第4行–获得所有已安装的包的列表。
- 第5行–通过调用install方法安装Ruby包。可以通过包名本身直接调用install助手方法。
事情就是这么简单。
文件管理
Cfruby还可以帮助管理系统上的文件。通过使用Cfruby提供的方法,可以轻松地创建、编辑、删除、更改所有权和更改许可等等。
清单12.使用cfgrubyscript进行文件管理
require'rubygems' require_gem'cfruby' require'libcfruby/cfrubyscript' '/etc/ssh'.chown_mod('root','wheel','u=rw,g=r,o-rwx',`:recursive`=>true)
上述代码做什么事情?
第3行–更改文件“/etc/ssh”的所有者和组以及许可。直接从文件本身调用chown_mod()方法。这样,这是通过cfrubyscript的助手对象和方法实现的。注意,这里只用一行就实现了该功能。
所以,上述例子应该已经让您了解到Cfruby有多强大,使用它来管理系统有多容易。而且,由于提供了一套非常直观的类和方法,它使得系统管理的整个任务变得更加容易,也更加有趣。
关于Cfruby和它的那一整套功能还有很多需要知道的。它附带有一套很好的文档。建议您看一看这些文档,这样才能将这个Ruby库的全部威力释放出来。请查看参考资料小节,获取相关链接。
结束语
Ruby不仅可以与Rails框架一起用于Web应用程序开发。它还可以像脚本编程语言一样强大,作为通常的shell脚本编程的一个很好的替代品,常用于实现系统管理中的脚本编程需求。
通过使用Ruby的一套内建模块和一些外部的库,系统管理员可以变得更加高效,工作更加有趣。Ruby是一个非常有用、非常强大的工具,是每个系统管理员工具箱中必备的工具。