我有一些简单的shell脚本任务想要完成。
比如:从与某个正则表达式匹配的文件列表中选择工作目录下的一个文件。
我知道可以使用标准的bash和grep来完成这样的事情,但如果能够编写可在Windows和Linux上工作的快速脚本,而不需要记住大量命令行程序和标志等信息,那将是很好的。
我尝试过了,但最终还是搞混了一些信息,例如对当前目录的引用等。
因此问题是:我需要了解哪些Ruby库才能编写Ruby shell脚本?
我有一些简单的shell脚本任务想要完成。
比如:从与某个正则表达式匹配的文件列表中选择工作目录下的一个文件。
我知道可以使用标准的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
还有一个非常有用的标准库,叫做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
命令获取。
您的脚本路径也很容易获取。使用$0
可以获取shell的第一个参数,即您的脚本的相对路径。可以这样确定绝对路径:
#!/usr/bin/env ruby
require 'pathname'
p Pathname.new($0).realpath()
对于文件系统操作,我几乎总是使用Pathname。它是其他许多文件系统相关类的包装器。还有一个有用的类:Dir,File...
以下是其他答案中缺失的重要内容:通过全局数组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上进行类似的操作(尽管不太方便)。
这里有很多好的建议,所以我想再补充一点。
反引号(或重音符号)让你更容易地执行一些脚本操作。例如:
puts `find . | grep -i lib`
如果您使用反引号运行时遇到输出问题,会将内容发送到标准错误输出而非标准输出。请参考此建议。out = `git status 2>&1`
反引号用于字符串插值:
blah = 'lib'
`touch #{blah}`
你也可以在Ruby中使用管道。这是链接到我的博客,但它会链接回来,所以没关系 :) 在这个主题上可能有更高级的东西。
正如其他人所指出的,如果你想要更加严肃的操作,可以使用Rush:不仅作为Shell替代品(对我来说有点过于夸张),而且还是用于您的Shell脚本和程序的库。
在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}"`
请自行获取一份《Ruby脚本编程实用指南》。其中包含了很多有用的技巧,可以帮助你完成你想要做的事情。
这里还有一个有用的链接:http://rush.heroku.com/
我并没有太多使用过,但它看起来非常棒。
从网站上了解到:
Rush是Unix shell(如bash、zsh等)的替代品,它使用纯Ruby语法。在Rush中,你可以像在shell中一样通过文件进行grep操作、查找和停止进程、复制文件等等 - 现在你可以通过Ruby完成所有这些操作了。
script.rb
的脚本文件。请将其放置于:#!/usr/bin/env ruby
将以下命令作为第一行,然后执行chmod +x script.rb
以上答案对于在使用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
#!/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
#!/path/to/ruby
然后使文件可执行:
chmod a+x myscript.rb
然后你就可以开始了。