Как использовать Ruby для сценариев оболочки?
У меня есть несколько простых задач сценария для скриптов, которые я хочу сделать
Например: выбор файла в рабочем каталоге из списка файлов, соответствующих некоторому регулярному выражению.
Я знаю, что могу делать подобные вещи с помощью стандартных bash и grep, но мне было бы неплохо взломать быстрые скрипты, которые будут работать в Windows и Linux, без необходимости запоминать кучу программ командной строки и флагов и т.д.
Я попытался добиться этого, но в конечном итоге запутался, где я должен получать информацию, такую как ссылка на текущий каталог
Итак, вопрос в том, какие части библиотек Ruby мне нужно знать для написания сценариев оболочки ruby?
Ответы
Ответ 1
По умолчанию у вас уже есть доступ к 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)
Что довольно приятно
Ответ 2
Как уже говорили другие, ваша первая строка должна быть
#!/usr/bin/env ruby
И вы также должны сделать его исполняемым: (в оболочке)
chmod +x test.rb
Далее следует код ruby. Если вы откроете файл
File.open("file", "r") do |io|
# do something with io
end
файл открывается в текущем каталоге, который вы получите с помощью pwd
в оболочке.
Путь к вашему script также прост. С помощью $0
вы получите первый аргумент оболочки, который является относительным путем к вашему script. Абсолютный путь можно определить следующим образом:
#!/usr/bin/env ruby
require 'pathname'
p Pathname.new($0).realpath()
Для операций файловой системы я почти всегда использую Pathname. Это оболочка для многих других классов, связанных с файловой системой. Также полезно: Dir, File...
Ответ 3
Здесь что-то важное, что отсутствует в других ответах: параметры командной строки отображаются в оболочке Ruby script через массив ARGV (глобальный).
Итак, если у вас есть script, называемый 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.
Ответ 4
Здесь много хорошего совета, поэтому я хотел добавить немного больше.
-
Backticks (или back-ticks) позволяют вам делать некоторые сценарии намного проще. Рассматривать
puts 'find . | grep -i lib'
-
Если у вас возникнут проблемы с получением выходных данных, материал будет заменен стандартным err вместо стандартного. Используйте этот совет
out = 'git status 2>&1'
-
Backticks выполняет строчную интерполяцию:
blah = 'lib'
'touch #{blah}'
-
Вы можете трубить внутри Ruby. Это ссылка на мой блог, но он ссылается сюда, так что все в порядке :) Есть, вероятно, более продвинутые вещи на этой теме.
-
Как отмечали другие люди, если вы хотите серьезно стать, есть Rush: не только как замена оболочки (что для меня слишком заодно), но и как библиотека для вашего использования в сценариях и программах оболочки.
На Mac, используйте Applescript внутри Ruby для большей мощности. Вот мой скрипт shell_here
:
#!/usr/bin/env ruby
'env | pbcopy'
cmd = %[email protected] app "Terminal" to do script "$(paste_env)"@
puts cmd
'osascript -e "${cmd}"'
Ответ 5
Пойдите, сделайте себе копию Everyday Scripting with Ruby. В нем есть много полезных советов о том, как делать типы вещей, которые вы хотите сделать.
Ответ 6
Это также может быть полезно: http://rush.heroku.com/
Я не использовал его много, но выглядит довольно круто.
С сайта:
rush является заменой для оболочки unix (bash, zsh и т.д.), которая использует чистый синтаксис Ruby. Grep через файлы, находить и убивать процессы, копировать файлы - все, что вы делаете в оболочке, теперь в Ruby
Ответ 7
скажем, вы пишете свой script.rb
script. говоря:
#!/usr/bin/env ruby
в качестве первой строки и выполните chmod +x script.rb
Ответ 8
Если вы хотите написать более сложные рубиновые скрипты, эти инструменты могут помочь:
Например:
Они дают вам быстрый старт для написания собственных сценариев, особенно "приложение командной строки".
Ответ 9
"Как написать ruby" немного выходит за рамки SO.
Но чтобы превратить эти рубиновые скрипты в исполняемые скрипты, поставьте это как первую строку вашего ruby script:
#!/path/to/ruby
Затем сделайте исполняемый файл:
chmod a+x myscript.rb
и уходите.
Ответ 10
Поместите это в начало вашего script.rb
#!/usr/bin/env ruby
Затем отметьте его как исполняемый файл:
chmod +x script.rb
Ответ 11
В ruby константа __FILE__
всегда даст вам путь к script, который вы используете.
В 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. Это просто и очень помогает вам.
Ответ 13
Вышеуказанный ответ интересен и очень полезен при использовании Ruby в качестве оболочки script. Для меня я не использую 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 script может быть 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