首页 文章

如何使用Ruby进行shell脚本编写?

提问于
浏览
160

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

例如:从与某些正则表达式匹配的文件列表中选择工作目录中的文件 .

我知道我可以使用标准的bash和grep做这种事情,但我很高兴能够破解可以在windows和linux中运行的快速脚本,而不必记住一堆命令行程序和标志等 .

我试图让这种情况发生,但最终对我应该获取信息的地方感到困惑,例如对当前目录的引用

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

13 回答

  • 4

    将它放在script.rb的开头

    #!/usr/bin/env ruby
    

    然后将其标记为可执行:

    chmod +x script.rb
    
  • 21

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

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

    从网站:

    rush是使用纯Ruby语法的unix shell(bash,zsh等)的替代品 . Grep文件,查找和终止进程,复制文件 - 您在shell中执行的所有操作,现在都在Ruby中

  • 6

    假设你写了 script.rb 脚本 . 放:

    #!/usr/bin/env ruby
    

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

  • 3

    去给自己一份Everyday Scripting with Ruby . 它有很多关于如何做你想要做的事情的有用提示 .

  • 4

    在ruby中,常量 __FILE__ 将始终为您提供正在运行的脚本的路径 .

    在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__)
    
  • 12

    webmat的答案是完美的 . 我只想指出你的补充 . 如果必须为脚本处理命令行参数很多,则应使用optparse . 它很简单,可以帮助您 .

  • 4

    以下是其他答案中缺少的重要内容:命令行参数通过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中执行类似(虽然不太方便)的操作 .

  • 108

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

    例如:

    • thor(脚本框架)

    • gli(git like interface)

    • methadone(用于创建简单工具)

    它们让您快速开始编写自己的脚本,尤其是“命令行应用程序” .

  • 66

    默认情况下,您已经可以访问DirFile,它们本身非常有用 .

    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)
    

    这很不错

  • 10

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

    #!/usr/bin/env ruby
    

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

    chmod +x test.rb
    

    然后遵循ruby代码 . 如果您打开一个文件

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

    该文件在shell中使用 pwd 获取的当前目录中打开 .

    脚本的路径也很简单 . 使用 $0 ,您将获得shell的第一个参数,它是脚本的相对路径 . 绝对路径可以这样确定:

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

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

  • 3

    当使用Ruby作为shell脚本时,上面的答案很有趣并且非常有用 . 对我来说,我不使用Ruby作为我的日常语言,我更喜欢使用ruby作为流量控制,仍然使用bash来完成任务 .

    一些辅助函数可用于测试执行结果

    #!/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
    
  • 142

    这里有很多好建议,所以我想补充一点 .

    • Backticks(或back-ticks)让你更轻松地完成一些脚本编写工作 . 考虑
    puts `find . | grep -i lib`
    
    • 如果你在获得反引号的输出时遇到问题,那么这些东西将是标准错误而不是标准输出 . Use this advice
    out = `git status 2>&1`
    
    • 反引号执行字符串插值:
    blah = 'lib'
    `touch #{blah}`
    

    在Mac上,使用Ruby内部的Applescript获得更多功能 . 这是我的 shell_here 脚本:

    #!/usr/bin/env ruby
    `env | pbcopy` 
    cmd =  %Q@tell app "Terminal" to do script "$(paste_env)"@
    puts cmd
    
    `osascript -e "${cmd}"`
    
  • 31

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

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

    #!/path/to/ruby
    

    然后做可执行文件:

    chmod a+x myscript.rb
    

    然后你走吧

相关问题