уровне, мы продемонстрируем несколько полезных приемов.

Выстроить эту главу было трудно, поскольку есть много способов логически сгруппировать рассматриваемый материал. Если вы не смогли найти нужную тему там, где ожидали, попробуйте просмотреть другие разделы.

Кроме того, многие вопросы, которые можно было бы включить сюда, вошли в другие главы. Обратите внимание, в частности, на главу 10, где рассматриваются ввод/вывод и атрибуты файлов; эта информация часто бывает полезна при написании сценариев.

14.1. Запуск внешних программ

Никакой язык не может использоваться в качестве «клея», если он не позволяет запускать внешние программы. В Ruby для этого есть несколько способов.

Не могу не обмолвиться о том, что перед запуском внешней программы неплохо бы понять, что она делает. Я имею в виду вирусы и другие потенциально разрушительные программы. Не запускайте произвольную командную строку, особенно поступившую из внешнего источника. Это касается не только приложений, ориентированных на Web.

14.1.1. Методы system и exec

Метод system (из модуля Kernel) эквивалентен одноименной функции из библиотеки языка С. Он выполняет указанную команду в отдельной оболочке.

system('/usr/games/fortune')

# Вывод направляется, как обычно, на stdout...

Второй параметр, если он задан, должен содержать список аргументов; как правило, аргументы можно задавать и в командной строке — эффект будет тот же. Разница лишь в том, что алгоритм расширения имени файла применяется только к первой из переданных строк.

system('rm', '/tmp/file1')

system('rm /tmp/file2')

# Оба варианта годятся.

# А тут есть различие...

system('echo *')   # Печатается список всех файлов.

system('echo','*') # Печатается звездочка (расширение

                   # имени файла не производится).

# Более сложные командные строки тоже работают.

system('ls -l | head -n |')

Посмотрим, как это будет работать в семействе операционных систем Windows. В случае с простой исполняемой программой поведение должно быть таким же, как в UNIX. В зависимости от варианта Ruby для вызова встроенных в оболочку команд может потребоваться запуск cmd.ехе  — интерпретатора команд в Windows (в некоторых версиях ОС он называется command.com). Ниже приведены примеры запуска внешней и встроенной команды:

system('notepad.ехе','myfile.txt') # Никаких проблем...

system('cmd /с dir','somefile')    # 'dir' - встроенная команда!

Другое решение — воспользоваться библиотекой Win32API и определить собственный вариант метода system.

require 'Win32API'

def system(cmd)

 sys = Win32API.new('crtdll', 'system', ['P'], 'L')

 sys.Call(cmd)

end

system('dir') # cmd /с необязательно!

Таким образом, можно добиться более-менее системно-независимого поведения system. Но если вы хотите запомнить выведенную программой информацию (например, в переменной), то system — не лучший способ (см. следующий раздел).

Упомяну еще метод exec. Он ведет себя аналогично system с тем отличием, что новый процесс замещает текущий. Поэтому код, следующий за exec, исполняться не будет.

puts 'Содержимое каталога:'

exec('ls', '-l')

puts 'Эта строка никогда не исполняется!'

14.1.2. Перехват вывода программы

Простейший способ перехватить информацию, выведенную программой, — заключить команду в обратные кавычки, например:

listing = `ls -l` # Одна строка будет содержать несколько строчек (lines).

now = `date`      # 'Mon Mar 12 16:50:11 CST 2001'

Обобщенный ограничитель %x вызывает оператор обратных кавычек (который в действительности является методом модуля Kernel). Работает он точно так же:

listing = %x(ls -l)

now = %x(date)

Применение %x бывает полезно, когда подлежащая исполнению строка содержит такие символы, как одиночные и двойные кавычки.

Поскольку обратные кавычки — это на самом деле метод (в некотором смысле), то его можно переопределить. Изменим его так, чтобы он возвращал не одну строку, а массив строк. Конечно, при этом мы создадим синоним старого метода, чтобы его можно было вызвать.

alias old_execute `

def `(cmd)

 out = old_execute(cmd) # Вызвать исходный метод обратной кавычки.

 out.split(' ') # Вернуть массив строк!

end

entries = `ls -l /tmp`

num = entries.size          # 95

first3lines = %x(ls -l | head -n 3)

how_many = first3lines.size # 3

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату