time2 = ENV['time2']
args1 = ParseDate.parsedate(time1)
args2 = ParseDate.parsedate(time2)
args1 = args1[0..5]
args2 = args2[0..5]
t1 = Time.local(*args1)
t2 = Time.local(*args2)
diff = t2 — t1
puts diff
EOF
echo 'Прошло секунд = ' $elapsed
В данном случае оба исходных значения передаются в виде переменных окружения (которые необходимо экспортировать). Строки, читающие эти значения, можно было бы записать так:
time1='$time1' # Включить переменные оболочки непосредственно
time2='$time2' # в строку...
Но возникающие при этом проблемы очевидны. Очень трудно понять, имеется ли в виду переменная bash или глобальная переменная Ruby. Возможна также путаница при экранировании и расстановке кавычек.
Флаг -e
позволяет создавать однострочные Ruby-сценарии. Вот пример обращения строки:
#!/usr/bin/bash
string='Francis Bacon'
ruby -e 'puts '$string'.reverse' | read reversed
# $reversed теперь равно 'nocaB sicnarF'
Знатоки UNIX заметят, что awk
использовался подобным образом с незапамятных времен.
14.9.3. Получение и установка кодов завершения
Метод exit
возбуждает исключение SystemExit
и в конечном счете возвращает указанный код завершения операционной системе (или тому, кто его вызвал). Этот метод определен в модуле Kernel
. Метод exit!
отличается от него в двух отношениях: он не выполняет зарегистрированные обработчики завершения и по умолчанию возвращает - 1.
# ...
if (all_OK)
exit # Нормально (0).
else
exit! # В спешке (-1).
end
Когда операционная система печатает возвращенный Ruby код (например, выполнив команду echo $?
), мы видим то же самое число, что было указано в программе. Если завершается дочерний процесс, то код его завершения, полученный с помощью метода wait2
(или waitpid2
), будет сдвинут влево на восемь битов. Это причуда стандарта POSIX, которую Ruby унаследовал.
child = fork { sleep 1; exit 3 }
pid, code = Process.wait2 # [12554,768]
status = code << 8 #3
14.9.4. Работает ли Ruby в интерактивном режиме?
Чтобы узнать, работает ли программа в интерактивном режиме, нужно проверить стандартный ввод. Метод isatty?
возвращает true
, если устройство интерактивное, а не диск или сокет. (Для Windows этот метод не реализован.)
if STDIN.isatty?
puts 'Привет! Я вижу, вы печатаете'
puts 'на клавиатуре.'
else
puts 'Входные данные поступают не с клавиатуры.'
end
14.9.5. Определение текущей платформы или операционной системы
Если программа хочет знать, в какой операционной системе исполняется, то может опросить глобальную константу RUBY_PLATFORM
. В ответ будет возвращена загадочная строка (что- то вроде i386-cygwin
или sparc-solaris2.7
), содержащая информацию о платформе, для которой был собран интерпретатор Ruby.
Поскольку мы в основном работаем с вариантами UNIX (Solaris, AIX, Linux) и Windows (98, NT, 2000, XP), то считаем полезным следующий очень грубый код. Он отличает UNIX от Windows (бесцеремонно отправляя всех остальных в категорию «прочие»).
def os_family
case RUBY_PLATFORM
when /ix/i, /ux/i, /gnu/i,
/sysv/i, /solaris/i,
/sunos/i, /bsd/i
'unix'
when /win/i, /ming/i
'windows'
else
'other'
end
end
Этот небольшой набор регулярных выражений корректно распознает абсолютное большинство платформ. Конечно, это весьма неуклюжий способ обработки системных зависимостей. Даже если вы правильно определите семейство ОС, отсюда еще не следует, что нужная вам функциональность имеется