Groovy + bash: двойная мощь

Groovy — скриптовой язык, т.е предназначен для сиюминутных решений. Такое же назначение и у bash. Жаль только синтаксисы их уж совсем разные. Однако, как оказалось, два эти языка можно совместить элегантным образом.



Начнем с того, что Java (а значит и Groovy) может выполнять системные команды. Для этого используется класс Runtime:

Runtime.getRuntime().exec("mkdir /tmp/hzdir");

В Groovy — еще проще:

"mkdir /tmp/hzdir".execute()

Проблема в том, что такие процессы выполняются в асинхронном режиме, а чаще всего нужно дождаться результата работы предыдущей команды, прежде чем запустить следующую. поэтому приходится писать так:
proc = "mkdir /tmp/hzdir".execute()
proc.waitFor()
proc = "sudo mount /dev/hdz1 /tmp/hzdir".execute()
proc.waitFor()

Уже некрасиво: в скобах и кавычках, а также вспомогательных строках теряется смысл bash-скрипта. Но мы же имеем дело с Groovy и его великолепными возможностями по обработке строк! Поэтому пишем:

tmpDit = '/tmp/hzdir'
device = '/dev/hdz1'

cmd = """
 rm -Rf $tmpDir             // bash-скрипт в чистом виде;
 mkdir  $tmpDir             // из Groovy в него приходят
 sudo mount $device $tmpDir // динамические параметры
"""

cmd.eachLine{"${it}".execute()}


Вот, совсем другое дело. И логика bash-скрипта видна, и динамическая подстановка Groovy задействована. Правда, есть маленькая проблема: Java (и Groovy) «спотыкаются» о лишние пробелы, встречающиеся в командной строке. Поэтому лучше передавать методу execute() не строку, а массив из команды и ее аргументов, избавленных от лишних пробелов, т.е. последний блок лучше оформить так:

. . .

cmd.eachLine{
 sa = it.trim().split(/\s+/)
 sa.execute()
}
  • +9
  • 27 июля 2010, 15:48
  • yababay

Комментарии (2)

RSS свернуть / развернуть
+
0
Интересно! Хороший вариант!
avatar

Markony

  • 27 июля 2010, 17:35
+
0
Неплохо, но конечно уже не совсем переносимо)
avatar

Sergei_T

  • 27 июля 2010, 20:23

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.