我如何使用Ruby进行shell脚本?

我有一些简单的shell脚本任务,我想要做的

例如:从匹配一些正则expression式的文件列表中select工作目录中的文件。

我知道我可以使用标准的bash和grep来做这种事情,但是我会很高兴能够攻破快速脚本,这些脚本可以在windows和linux下工作,而不必记住一堆命令行程序和标志等。

我试图让这个去,但结束了我应该得到的信息,如引用到当前目录的困惑

所以问题是Ruby库的哪些部分我需要知道编写ruby shell脚本?

默认情况下,您已经可以访问Dir和File ,这些都是非常有用的。

Dir['*.rb'] #basic globs Dir['**/*.rb'] #** == any depth of directory, including current dir. #=> array of relative names File.expand_path('~/file.txt') #=> "/User/mat/file.txt" File.dirname('dir/file.txt') #=> 'dir' File.basename('dir/file.txt') #=> 'file.txt' File.join('a', 'bunch', 'of', 'strings') #=> 'a/bunch/of/strings' __FILE__ #=> the name of the current file 

从stdlib也是有用的FileUtils

 require 'fileutils' #I know, no underscore is not ruby-like include FileUtils # Gives you access (without prepending by 'FileUtils.') to cd(dir, options) cd(dir, options) {|dir| .... } pwd() mkdir(dir, options) mkdir(list, options) mkdir_p(dir, options) mkdir_p(list, options) rmdir(dir, options) rmdir(list, options) ln(old, new, options) ln(list, destdir, options) ln_s(old, new, options) ln_s(list, destdir, options) ln_sf(src, dest, options) cp(src, dest, options) cp(list, dir, options) cp_r(src, dest, options) cp_r(list, dir, options) mv(src, dest, options) mv(list, dir, options) rm(list, options) rm_r(list, options) rm_rf(list, options) install(src, dest, mode = <src's>, options) chmod(mode, list, options) chmod_R(mode, list, options) chown(user, group, list, options) chown_R(user, group, list, options) touch(list, options) 

这是相当不错的

正如其他人已经说过,你的第一行应该是

 #!/usr/bin/env ruby 

而且你也必须使它可执行:(在shell中)

 chmod +x test.rb 

然后遵循ruby代码。 如果你打开一个文件

 File.open("file", "r") do |io| # do something with io end 

该文件在当前目录中打开,你将在shell中使用pwd

你的脚本的path也很容易获得。 用$0获得shell的第一个参数,这是脚本的相对path。 绝对path可以这样确定:

 #!/usr/bin/env ruby require 'pathname' p Pathname.new($0).realpath() 

对于文件系统操作,我几乎总是使用path名。 这是许多其他文件系统相关类的包装。 也很有用:Dir,File …

以下是其他答案中缺less的一些重要信息:通过ARGV(全局)数组,将命令行参数显示给Ruby shell脚本。

所以,如果你有一个名为my_shell_script的脚本:

 #!/usr/bin/env ruby puts "I was passed: " ARGV.each do |value| puts value end 

…使其可执行(如其他人所述):

 chmod u+x my_shell_script 

并称之为如此:

 > ./my_shell_script one two three four five 

你会得到这个:

 I was passed: one two three four five 

参数与文件名扩展很好地结合在一起:

 ./my_shell_script * I was passed: a_file_in_the_current_directory another_file my_shell_script the_last_file 

大多数这只适用于UNIX(Linux,Mac OS X),但是你可以在Windows中做类似(虽然不太方便)的事情。

这里有很多很好的build议,所以我想补充一点点。

  1. 反引号(或反标)让你做一些脚本的东西更容易。 考虑

     puts `find . | grep -i lib` 
  2. 如果遇到反引号输出的问题,这些东西就会标准化,而不是标准化。 使用这个build议

     out = `git status 2>&1` 
  3. 反引号做string插值:

     blah = 'lib' `touch #{blah}` 
  4. 你也可以在Ruby里面pipe道 。 这是一个链接到我的博客,但它链接到这里,所以没关系:)在这个主题上可能有更先进的东西。

  5. 正如其他人所指出的那样,如果你想认真对待Rush:不仅仅是作为一个shell替代品(这对我来说有点过分了),而且还可以作为你在shell脚本和程序中使用的库。

用Ruby来获得每日脚本的副本。 它有很多有用的技巧,如何做你想做的事情的types。

这可能也有帮助: http : //rush.heroku.com/

我没有用太多,但看起来很酷

来自网站:

rush是使用纯Ruby语法的unix shell(bash,zsh等)的替代品。 grep通过文件,find并杀死进程,复制文件 – 你在shell中做的所有事情,现在在Ruby中

比方说,你写你的script.rb脚本。 放:

 #!/usr/bin/env ruby 

作为第一行,并做一个chmod +x script.rb

当你想写更复杂的ruby脚本时,这些工具可能会有所帮助:

例如:

  • thor (一个脚本框架)

  • gli (git like界面)

  • 美沙酮 (用于创build简单的工具)

他们让你快速开始写自己的脚本,特别是“命令行应用程序”。

“我怎么写ruby”有点超出了SO的范围。

但要将这些ruby脚本转换为可执行脚本,请将其作为ruby脚本的第一行:

 #!/path/to/ruby 

然后使文件可执行:

 chmod a+x myscript.rb 

并离开你去。

把它放在script.rb的开头

 #!/usr/bin/env ruby 

然后将其标记为可执行的:

 chmod +x script.rb 

webmat的答案是完美的。 我只是想指出你一个补充。 如果您必须处理脚本的命令行参数,则应使用optparse 。 这很简单,并帮助你巨大的。

在ruby中,常量__FILE__总会给你你正在运行的脚本的path。

在Linux上, /usr/bin/env是你的朋友:

 #! /usr/bin/env ruby # Extension of this script does not matter as long # as it is executable (chmod +x) puts File.expand_path(__FILE__) 

在Windows上,它取决于.rb文件是否与ruby关联。 如果他们是:

 # This script filename must end with .rb puts File.expand_path(__FILE__) 

如果他们不是,你必须明确地调用他们的ruby,我使用中间.cmd文件:

my_script.cmd:

 @ruby %~dp0\my_script.rb 

my_script.rb:

 puts File.expand_path(__FILE__) 

上面的答案在使用Ruby作为shell脚本时非常有趣。 对我而言,我并不使用Ruby作为日常语言,我更喜欢使用ruby作为stream控制,而仍然使用bash来完成这些任务。

一些辅助函数可以用来testing执行结果

 #!/usr/bin/env ruby module ShellHelper def test(command) `#{command} 2> /dev/null` $?.success? end def execute(command, raise_on_error = true) result = `#{command}` raise "execute command failed\n" if (not $?.success?) and raise_on_error return $?.success? end def print_exit(message) print "#{message}\n" exit end module_function :execute, :print_exit, :test end 

与助手,ruby脚本可以是bash一样的:

 #!/usr/bin/env ruby require './shell_helper' include ShellHelper print_exit "config already exists" if test "ls config" things.each do |thing| next if not test "ls #{thing}/config" execute "cp -fr #{thing}/config_template config/#{thing}" end