쉘 스크립팅에 Ruby를 어떻게 사용합니까?


165

내가하고 싶은 간단한 쉘 스크립팅 작업이 있습니다.

예를 들면 다음과 같습니다. 일부 정규식과 일치하는 파일 목록에서 작업 디렉토리의 파일을 선택합니다.

나는 표준 bash와 grep을 사용하여 이런 종류의 일을 할 수 있다는 것을 알고 있지만 명령 줄 프로그램과 플래그 등을 기억하지 않고도 Windows와 Linux에서 작동하는 빠른 스크립트를 해킹 할 수 있다는 것이 좋을 것입니다.

나는이 일을하려고했지만 현재 디렉토리에 대한 참조와 같은 정보를 어디에서 얻을 수 있는지 혼란스러워졌습니다.

질문은 루비 쉘 스크립트를 작성하기 위해 루비 라이브러리의 어떤 부분을 알아야합니까?


3
아마 좋은 대답은 아니지만 시스템 관리를위한 실용적인 루비는 훌륭한 참고 자료입니다. amazon.com/Practical-System-Administration-Experts-Source/dp/…
exiquio

답변:


148

기본적으로 이미 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)

어느 쪽이 좋습니까


110

다른 사람들이 이미 말했듯이 첫 번째 줄은

#!/usr/bin/env ruby

그리고 당신은 또한 그것을 실행 가능하게 만들어야합니다 : (쉘에서)

chmod +x test.rb

그런 다음 루비 코드를 따릅니다. 파일을 열면

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

파일은 현재 디렉토리에서 열립니다. pwd 쉘에서 .

스크립트 경로도 간단합니다. 함께 $0사용하면 스크립트에 대한 상대 경로입니다 쉘의 첫 번째 인수를 얻을. 절대 경로는 다음과 같이 결정될 수 있습니다.

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

파일 시스템 작업의 경우 거의 항상 경로 이름을 사용합니다. 이것은 다른 많은 파일 시스템 관련 클래스의 래퍼입니다. 또한 유용합니다 : Dir, File ...


66

다른 답변에서 누락 된 중요한 사항이 있습니다. 명령 행 매개 변수는 ARGV (전역) 배열을 통해 Ruby 쉘 스크립트에 노출됩니다.

따라서 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에서는 비슷한 (편리하지는 않지만) 할 수 있습니다.


32

여기에는 좋은 조언이 많이 있으므로 조금 더 추가하고 싶었습니다.

  1. 백틱 (또는 백틱)을 사용하면 일부 스크립팅 작업을 훨씬 쉽게 수행 할 수 있습니다. 치다

    puts `find . | grep -i lib`
  2. 백틱의 출력을 얻는 데 문제가 발생하면 표준 아웃 대신 표준 오류가 발생합니다. 이 조언을 사용하십시오

    out = `git status 2>&1`
  3. 백틱은 문자열 보간을 수행합니다.

    blah = 'lib'
    `touch #{blah}`
  4. 루비 내부도 파이프 할 수 있습니다 . 내 블로그에 대한 링크이지만 여기로 다시 연결되므로 괜찮습니다.

  5. 다른 사람들이 지적했듯이, 진지하게하고 싶다면 Rush가 있습니다 : 쉘 교체 (나에게 너무 까다 롭습니다)뿐만 아니라 쉘 스크립트 및 프로그램에서 사용하기위한 라이브러리 이기도 합니다.


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}"`

코드를 포맷하기 위해 코드를 4 칸 더 들여 쓰기해야했습니다. 나는 또한 백틱을 되돌려 놓았지만 루비를 전혀 모른다. 그래서 당신이 의도 한 것인지 확인하고 싶을 것이다.
Bill the Lizard

@Bliz the Lizard, 그래, 그게 내가 필요한 '간계'였다. 도와 주셔서 감사합니다.
Dan Rosenstark


22

RubyEveryday Scripting 의 사본을 받으십시오 . 원하는 유형의 작업을 수행하는 방법에 대한 유용한 팁이 많이 있습니다.


2
좋은 책, 나는 지금 읽고 있습니다 : 그것은 선 코드 여행처럼 느껴집니다. TDD를 모른다면 TDD의 기본 사항을 배우게됩니다.
Sébastien RoccaSerra

이 책에는 좋은 정보가 있지만 숙련 된 프로그래머에게는 많은 오버 헤드가 있다고 생각합니다.
D 합병

12

도움이 될 수도 있습니다 : http://rush.heroku.com/

많이 사용하지는 않았지만 꽤 멋져 보입니다.

사이트에서 :

rush는 순수 Ruby 구문을 사용하는 유닉스 쉘 (bash, zsh 등)을 대체합니다. 파일을 살펴보고, 프로세스를 찾아서 죽이고, 파일을 복사하십시오-이제는 Ruby에서 쉘에서하는 모든 일


2
러쉬 : 아니요. 왜? groups.google.com/group/ruby-shell/browse_thread/thread/… 훌륭하지만 바퀴 달린 사람은 없습니다.
Dan Rosenstark

12

script.rb스크립트 를 작성한다고 가정 해 봅시다 . 놓다:

#!/usr/bin/env ruby

첫 번째 줄로 chmod +x script.rb


7

더 복잡한 루비 스크립트를 작성하려면 다음 도구가 도움이 될 수 있습니다.

예를 들면 다음과 같습니다.

  • thor (스크립팅 프레임 워크)

  • gli (git like interface)

  • 메타돈 (간단한 도구 생성 용)

그들은 당신에게 당신의 자신의 스크립트, 특히 '명령 줄 앱'을 빠르게 시작할 수있게합니다.


5

위의 답변은 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

도우미를 사용하면 루비 스크립트가 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

이봐, 대단해, ​​고마워!
Victor Martins

4

"루비를 작성하는 방법"은 SO의 범위를 약간 벗어납니다.

그러나이 루비 스크립트를 실행 가능한 스크립트로 바꾸려면 이것을 루비 스크립트의 첫 줄로 넣으십시오.

#!/path/to/ruby

그런 다음 파일을 실행 가능하게 만드십시오.

chmod a+x myscript.rb

그리고 당신은 간다.


4

이것을 스크립트 시작 부분에 배치하십시오.

#!/usr/bin/env ruby

그런 다음 실행 파일로 표시하십시오.

chmod +x script.rb

3

webmat 의 답변 은 완벽합니다. 나는 단지 당신에게 추가를 지적하고 싶습니다. 스크립트의 명령 줄 매개 변수를 많이 다루어야하는 경우 optparse 를 사용해야합니다 . 간단하고 당신을 도와줍니다.


3

루비에서 상수 __FILE__는 항상 실행중인 스크립트의 경로를 제공합니다.

리눅스에서 /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__)

그렇지 않은 경우 명시 적으로 루비를 호출해야하며 중간 .cmd 파일을 사용합니다.

my_script.cmd :

@ruby %~dp0\my_script.rb

my_script.rb :

puts File.expand_path(__FILE__)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.