singlepost

Почему Руби рулит << На главную или назад  

По ходу дела мне надо администрировать несколько серверов. Повторять некоторые операции с перезаходом через ssh надоедает на третьем разе.

Что мы делаем? Программу, выполняющую одну и ту же команду на нескольких машинах.

~$ touch all
~$ chmod +x all
~$ ln -s ~/all /bin/all

<vkcode.ujs.net.ru>
#!/usr/bin/ruby
hosts = `cat /etc/hosts | egrep 'video[0-9]+.local'| awk '{print $1}'`
threads = []
hosts.each_line do |h|
threads << Thread.new(h) do |host|
puts `ssh #{host.strip} '#{ARGV[0]}'`
end
end
threads.each{|t|t.join}
</vkcode.ujs.net.ru>

Usage:
~$ all 'ls -la'
(выведет содержимое ~/ на каждой машине)

В этом коде мы делаем простую вещь: вынимаем нужные нам адреса из /etc/hosts и рассылаем им запросы.

Чтобы машины не стояли без дела, все команды выполняются параллельно — в отдельных потоках (Thread.new do … end)

Чтобы все запущенные потоки не были убиты при выходе из скрипта (основного потока), в конце ожидаем окончания всех потоков:
threads.each{|t|t.join}

Но это все еще мелочи. Таким скриптом я пользовался пару месяцев пока мне не пришлось разослать *синхронные* запросы, т.е. так, чтобы они выполнялись действительно друг за другом.
Самое очевидное — закомментировать создание потока, удалить упоминание массива threads. Но это слишком грязно, да и потом возвращать обратно придется. Или создавать отдельный скрипт. Или писать большой if.Но можно всего лишь дожидаться окончания потока сразу после его создания:

threads << Thread.new do; …; end # создали
threads.pop.join if ARGV[1] == 'sync' # подождали

threads.pop выкидывает последний добавленный поток, а join останавливает главный поток до окончания дочернего. Причем, скрипт сразу универсальный: фича работает если второй аргумент — sync.

30 ответов в теме “Почему Руби рулит”

  1. 4
    Олег Андреев ответил:

    Ну да, использовался. А японцы, как увидели в 1995 году, какую вещь замутил Матц, сразу съехали с Перла на Рубин. А в Европе только последние два года народ въезжает в тему. Плюс, у европейцев мышление немного другое. Они сразу начинают вести разговоры о том "зачем переписывать перловые скрипты", "будет ли скейлиться", "я привык" и т.п. Японцы просто берут и пробуют. А дальше — понравится / не понравится. Причем, больше всего меня веселят конспирологические подозрения европейцев: например, будто кто-то агитирует переписывать существующие скрипты. Я пользуюсь чужими перловыми скриптами и не помер, хотя все своё — на рубине.

    PS. Разумеется, пиарим Руби. Впрочем, ты можешь сделать тему про перл, где нарисовать почему крут именно он :-) Как у перла дела с тредами?

  2. 3
    Ваня Григорьев ответил:

    Олег, а почему именно так названа тема? Опять пиарим Руби? ;)
    Ну а если серьёзно, то вышеупомянутый код без проблем переписывается на перле с точно такой же функциональностью.

    Собственно, раньше для автоматизации подобного рода именно Перл и использовался.

  3. 2
    Олег Андреев ответил:

    Да, капистрано — вещь! То, что описано выше (~/all) работает так:

    $ cap invoke COMMAND="ls -la"

    А для predefined-задач:

    $ cap some_task

    Вообще, очень сочувствую тем, у кого виндоус-машины. Там нет нормального ssh и sh (насколько мне известно) и капистрано работать с девелоперской машины не сможет. Линукс, БСД и макось are welcome. Или cygwin на винде, хотя про него ничего не знаю. Может, и под SFU (windows services for unix) будет работать. Но там те же проблемы, что и у cygwin — виртуализация среды и, как следствие, вторжение в ваши правила организации рабочего места.

  4. 1
    Олег Андреев ответил:

    Мне посоветовали изучить Capistrano. Радостей для админа там вагон и маленькая тележка.

    //www.capify.org/getting-started/basics

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.