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 à partir d'une liste de fichiers correspondant à une expression régulière.
Je sais que je peux faire ce genre de chose en utilisant Bash standard et grep mais je serais bien de pouvoir pirater des scripts rapides qui fonctionneront sous windows et linux sans que je doive mémoriser un tas de programmes et de drapeaux en ligne de commande, etc.
J'ai essayé de faire avancer ça mais j'ai fini par devenir confus sur l'endroit où je devrais obtenir des informations telles qu'une référence au répertoire courant
La question est donc de savoir quelles parties des bibliothèques Ruby dois-je savoir pour écrire des scripts shell ruby?
13 réponses
Par défaut, vous avez déjà accès à Dir et Fichier, qui sont assez utiles par 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
Aussi utile à partir 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)
Ce qui est plutôt sympa
, 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 courant, vous obtiendriez 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 à votre script. Le chemin absolu peut être déterminé comme que:
#!/usr/bin/env ruby
require 'pathname'
p Pathname.new($0).realpath()
Pour les opérations du système de fichiers, j'utilise presque toujours Pathname. Ceci est un wrapper pour beaucoup d'autres classes liées au système de fichiers. Aussi utile: Dir, fichier...
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-le comme ceci:
> ./my_shell_script one two three four five
, Vous obtiendrez ceci:
I was passed:
one
two
three
four
five
Les arguments fonctionnent bien avec l'expansion du 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 cela ne fonctionne que sur UNIX (Linux, Mac OS X), mais vous pouvez faire des choses similaires (bien que moins pratiques) dans Windows.
Il y a beaucoup de bons conseils ici, donc je voulais en ajouter un tout petit peu plus.
-
Les Backticks (ou back-ticks) vous permettent de faire des scripts beaucoup plus facilement. Considérer
puts `find . | grep -i lib`
-
Si vous rencontrez des problèmes avec l'obtention de la sortie des backticks, les choses vont se tromper standard au lieu de standard out. utilisez ce conseil
out = `git status 2>&1`
-
Les Backticks font une interpolation de chaîne:
blah = 'lib' `touch #{blah}`
Vous pouvez tuyau à l'intérieur Ruby, trop. C'est un lien vers mon blog, mais il renvoie ici donc c'est bon :) il y a probablement des choses plus avancées sur ce sujet.
Comme d'autres personnes l'ont noté, si vous voulez être sérieux, il y a Rush: pas seulement comme un remplacement de shell (ce qui est un peu trop loufoque pour moi) mais aussi comme une bibliothèque pour votre utilisation dans les scripts et programmes shell.
Sur Mac, utilisez Applescript dans Ruby pour plus de puissance. Voici mon script shell_here
:
#!/usr/bin/env ruby
`env | pbcopy`
cmd = %Q@tell app "Terminal" to do script "$(paste_env)"@
puts cmd
`osascript -e "${cmd}"`
Allez vous procurer une copie de Scripts quotidiens avec Ruby . Il a beaucoup de conseils utiles sur la façon de faire les types de choses que vous voulez faire.
Cela peut également être utile: http://rush.heroku.com/
Je ne l'ai pas beaucoup utilisé, mais ça a l'air plutôt cool
Du site:
Rush est un remplacement pour le shell unix (bash, zsh, etc) qui utilise la syntaxe Ruby pure. Grep à travers les fichiers, trouver et tuer les processus, copier des fichiers-Tout ce que vous faites dans le shell, maintenant dans Ruby
Disons que vous écrivez votre script script.rb
. mettre:
#!/usr/bin/env ruby
Comme première ligne et faites un chmod +x script.rb
Lorsque vous voulez écrire des scripts ruby plus complexes, ces outils peuvent vous aider:
Par exemple:
Ils vous donnent un démarrage rapide pour écrire vos propres scripts, en particulier'application de ligne de commande'.
"Comment é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 script ruby:
#!/path/to/ruby
Ensuite, rendez le fichier exécutable:
chmod a+x myscript.rb
Et vous partez.
Placez ceci au début de votre script.rb
#!/usr/bin/env ruby
Puis marquez-le comme exécutable:
chmod +x script.rb
Dans 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 oui ou non .les fichiers rb sont associés avec ruby. Si elles sont:
# This script filename must end with .rb
puts File.expand_path(__FILE__)
S'ils ne le sont pas, vous devez invoquer explicitement ruby sur eux, j'utilise un intermédiaire .fichier cmd:
My_script.cmd:
@ruby %~dp0\my_script.rb
My_script.rb:
puts File.expand_path(__FILE__)
La réponse ci-dessus est intéressante et très utile lors de l'utilisation de Ruby comme script shell. Pour moi, je n'utilise pas Ruby comme langage quotidien et je préfère utiliser ruby comme contrôle de flux uniquement et utiliser toujours bash pour faire les tâches.
Une fonction d'aide peut être utilisée 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 l'aide, le script ruby pourrait être bash comme:
#!/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