Программирование на языке Ruby - [171]
>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("\n") # Вернуть массив строк!
>end
>entries = `ls -l /tmp`
>num = entries.size # 95
>first3lines = %x(ls -l | head -n 3)
>how_many = first3lines.size # 3
Как видите, при таком определении изменяется также поведение ограничителя >%x
.
В следующем примере мы добавили в конец команды конструкцию интерпретатора команд, которая перенаправляет стандартный вывод для ошибок в стандартный вывод:
>alias old_execute `
>def `(cmd)
> old_execute(cmd + " 2>&1")
>end
>entries = `ls -l /tmp/foobar`
># "/tmp/foobar: No such file or directory\n"
Есть, конечно, и много других способов изменить стандартное поведение обратных кавычек.
14.1.3. Манипулирование процессами
В этом разделе мы обсудим манипулирование процессами, хотя создание нового процесса необязательно связано с запуском внешней программы. Основной способ создания нового процесса — это метод >fork
, название которого в соответствии с традицией UNIX подразумевает разветвление пути исполнения, напоминая развилку на дороге. (Отметим, что в базовом дистрибутиве Ruby метод >fork
на платформе Windows не поддерживается.)
Метод >fork
, находящийся в модуле >Kernel
(а также в модуле >Process
), не следует путать с одноименным методом экземпляра в классе >Thread
.
Существуют два способа вызвать метод >fork
. Первый похож на то, как это обычно делается в UNIX, — вызвать и проверить возвращенное значение. Если оно равно >nil
, мы находимся в дочернем процессе, в противном случае — в родительском. Родительскому процессу возвращается идентификатор дочернего процесса (pid).
>pid = fork
>if (pid == nil)
> puts "Ага, я, должно быть, потомок."
> puts "Так и буду себя вести."
>else
> puts "Я родитель."
> puts "Пора отказаться от детских штучек."
>end
В этом не слишком реалистичном примере выводимые строки могут чередоваться, а может случиться и так, что строки, выведенные родителем, появятся раньше. Но сейчас это несущественно.
Следует также отметить, что процесс-потомок может пережить своего родителя. Для потоков в Ruby это не так, но системные процессы — совсем другое дело.
Во втором варианте вызова метод >fork
принимает блок. Заключенный в блок код выполняется в контексте дочернего процесса. Так, предыдущий вариант можно было бы переписать следующим образом:
>fork do
> puts "Ага, я, должно быть, потомок."
> puts "Так и буду себя вести."
>end
>puts "Я родитель."
>puts "Пора отказаться от детских штучек."
Конечно, pid по-прежнему возвращается, мы просто не показали его.
Чтобы дождаться завершения процесса, мы можем вызвать метод >wait
из модуля >Process
. Он ждет завершения любого потомка и возвращает его идентификатор. Метод >wait2
ведет себя аналогично, только возвращает массив, содержащий РМ, и сдвинутый влево код завершения.
>Pid1 = fork { sleep 5; exit 3 }
>Pid2 = fork { sleep 2; exit 3 }
>Process.wait # Возвращает pid2
>Process.wait2 # Возвращает [pid1,768]
Чтобы дождаться завершения конкретного потомка, применяются методы >waitpid
и >waitpid2
.
>pid3 = fork { sleep 5; exit 3 }
>pid4 = fork { sleep 2; exit 3 }
>Process.waitpid(pid4,Process::WNOHANG) # Возвращает pid4
>Process.waitpid2(pid3, Process::WNOHANG) # Возвращает [pid3,768]
Если второй параметр не задан, то вызов может блокировать программу (если такого потомка не существует). Второй параметр можно с помощью ИЛИ объединить с флагом
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.