web-dev-qa-db-fra.com

Comment utiliser Ruby pour les scripts Shell?

J'ai quelques tâches de script shell simples que je veux faire

Par exemple: Sélection d'un fichier dans le répertoire de travail dans une liste de fichiers correspondant à une expression régulière.

Je sais que je peux faire ce genre de choses en utilisant bash et grep standard, mais je serais heureux de pouvoir pirater des scripts rapides qui fonctionneront sous windows et linux sans que je doive mémoriser un tas de programmes en ligne de commande et de drapeaux, etc.

J'ai essayé de faire avancer les choses, mais j'ai fini par être confus quant à l'endroit où je devrais obtenir des informations telles qu'une référence au répertoire actuel.

La question est donc de savoir quelles parties des bibliothèques Ruby dois-je connaître pour écrire Ruby) des scripts shell?

162
Willbill

Par défaut, vous avez déjà accès à Dir et File , qui sont très utiles en eux-mêmes.

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

Est également utile de la stdlib est 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)

Qui est jolie Nice

145
webmat

Comme les autres l’ont déjà dit, votre première ligne devrait être

#!/usr/bin/env Ruby

Et vous devez également le rendre exécutable: (dans le shell)

chmod +x test.rb

Suit ensuite le code Ruby. Si vous ouvrez un fichier

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

le fichier est ouvert dans le répertoire actuel que vous obtiendrez avec pwd dans le shell.

Le chemin d'accès à votre script est également simple à obtenir. Avec $0 vous obtenez le premier argument du shell, qui est le chemin relatif de votre script. Le chemin absolu peut être déterminé comme ça:

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

Pour les opérations de système de fichiers, j'utilise presque toujours Pathname. Il s'agit d'un wrapper pour la plupart des autres classes liées au système de fichiers. Aussi utile: Dir, Fichier ...

109
Georg Schölly

Voici quelque chose d'important qui manque dans les autres réponses: les paramètres de ligne de commande sont exposés à votre script shell = Ruby) via le tableau ARGV (global).

Donc, si vous aviez un script appelé my_Shell_script:

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

... le rendre exécutable (comme d'autres l'ont mentionné):

chmod u+x my_Shell_script

Et appelez comme ça:

> ./my_Shell_script one two three four five

Vous auriez ceci:

I was passed: 
one
two
three
four
five

Les arguments fonctionnent bien avec l'extension de nom de fichier:

./my_Shell_script *

I was passed: 
a_file_in_the_current_directory
another_file    
my_Shell_script
the_last_file

La plupart de ces opérations ne fonctionnent que sous UNIX (Linux, Mac OS X), mais vous pouvez effectuer des opérations similaires (bien que moins pratiques) dans Windows.

66
Craig Walker

Il y a beaucoup de bons conseils ici, alors je voulais ajouter un tout petit peu plus.

  1. Les backticks (ou back-ticks) vous permettent de créer des scripts beaucoup plus facilement. Considérer

    puts `find . | grep -i lib`
    
  2. Si vous rencontrez des problèmes pour obtenir la sortie de backticks, le contenu passe à l'erreur standard au lieu de la sortie standard. Utilisez ce conseil

    out = `git status 2>&1`
    
  3. Les backticks font une interpolation de chaîne:

    blah = 'lib'
    `touch #{blah}`
    
  4. Vous pouvez également utiliser Pipy dans Ruby . C'est un lien vers mon blog, mais il y a un lien ici donc ça va :) Il y a probablement des choses plus avancées sur ce sujet.

  5. Comme d'autres personnes l'ont noté, si vous voulez être sérieux, Rush: non seulement en remplacement de Shell (ce qui est un peu trop loufoque pour moi), mais aussi en tant que bibliothèque à utiliser dans Shell scripts et programmes


Sur Mac, utilisez Applescript dans Ruby pour plus de puissance. Voici mon Shell_here script:

#!/usr/bin/env Ruby
`env | pbcopy` 
cmd =  %Q@tell app "Terminal" to do script "$(paste_env)"@
puts cmd

`osascript -e "${cmd}"`
31
Dan Rosenstark

Allez chercher une copie de Everyday Scripting with Ruby . Il contient de nombreux conseils utiles sur la manière de faire le genre de choses que vous souhaitez faire.

21
Aaron Hinni

Cela pourrait aussi être utile: http://Rush.heroku.com/

Je ne l'ai pas beaucoup utilisé, mais j'ai l'air plutôt cool

Du site:

Rush remplace le shell unix (bash, zsh, etc.) qui utilise la syntaxe pure Ruby. Grep dans les fichiers, rechercher et tuer les processus, copier des fichiers - tout ce que vous faites dans le Shell, maintenant en rubis

12
craigp

disons que vous écrivez votre script.rb script. mettre:

#!/usr/bin/env Ruby

en première ligne et faire un chmod +x script.rb

10
Vasil

Lorsque vous voulez écrire des scripts plus complexes Ruby, ces outils peuvent vous aider:

Par exemple:

  • thor (un framework de script)

  • gli (git like interface)

  • méthadone (pour créer des outils simples)

Ils vous permettent de commencer rapidement à écrire vos propres scripts, en particulier les "applications en ligne de commande".

6
Bohr

Les réponses ci-dessus sont intéressantes et très utiles lors de l’utilisation de Ruby en tant que script shell. Pour moi, je n’utilise pas Ruby en tant que langue quotidienne et je préfère utiliser Ruby comme contrôle de flux uniquement et utilise toujours bash pour effectuer les tâches.

Certaines fonctions d'assistance peuvent être utilisées pour tester le résultat de l'exécution

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

Avec helper, le script Ruby pourrait être identique à celui-ci:

#!/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
4
Houcheng

Placez ceci au début de votre script.rb

#!/usr/bin/env Ruby

Puis marquez-le comme exécutable:

chmod +x script.rb
4
Daniel Beardsley

"Comment puis-je écrire Ruby" est un peu au-delà de la portée de SO.

Mais pour transformer ces scripts Ruby en scripts exécutables, mettez ceci comme première ligne de votre Ruby:

#!/path/to/Ruby

Ensuite, rendez le fichier exécutable:

chmod a+x myscript.rb

et vous partez.

4
Matthew Scharley

La réponse par webmat est parfaite. Je veux juste vous indiquer un ajout. Si vous devez traiter beaucoup de paramètres de ligne de commande pour vos scripts, vous devez utiliser optparse . C'est simple et vous aide énormément.

3
awenkhh

En Ruby, la constante __FILE__ vous donnera toujours le chemin du script que vous exécutez.

Sous Linux, /usr/bin/env est votre ami:

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

Sous Windows, cela dépend si les fichiers .rb sont associés à Ruby. Si ils sont:

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

S'ils ne le sont pas, vous devez explicitement appeler Ruby sur eux, j'utilise un fichier .cmd intermédiaire:

mon_script.cmd:

@Ruby %~dp0\my_script.rb

mon_script.rb:

puts File.expand_path(__FILE__)
3
bltxd