puts sh.pwd # /tmp
sh.popd
puts sh.pwd # /home
Для удобства в класс Shell
импортируются методы из различных источников, в том числе из класса File
, модуля FileTest
и библиотеки ftools.rb
. Это избавляет от необходимости выполнять require
, include
, создавать объекты, квалифицировать вызовы методов и т. д.
sh = Shell.new
flag1 = sh.exist? 'myfile' # Проверить существование файла.
sh.delete 'somefile' # Удалить файл.
sh.move '/tmp/foo', '/tmp/bar' # Переместить файл.
У библиотеки Shell
есть и другие возможности, которые мы здесь не рассматриваем. Дополнительную информацию ищите в документации.
14.4. Переменные окружения
Иногда необходимо обращаться к переменным окружения, которые являются связующим звеном между программой и внешним миром. Переменные окружения — это просто метки, связанные с некоторым текстом (обычно небольшим); в них хранятся, например, пути к файлам, имена пользователей и т.п.
Переменные окружения широко применяются в ОС UNIX. Система Windows (а еще раньше MS-DOS) позаимствовала эту идею у UNIX, поэтому приведенные ниже коды будут работать на обеих платформах.
14.4.1. Чтение и установка переменных окружения
Глобальная константа ENV
— это хэш, с помощью которого можно читать и изменять переменные окружения. В примере ниже мы читаем значение переменной PATH
, (в Windows вместо двоеточия нужно употреблять точку с запятой):
bypath = ENV['PATH']
# А теперь получим массив...
dirs = mypath.split(':')
А вот пример установки переменной. Новый процесс мы создали, чтобы проиллюстрировать две вещи. Во-первых, дочерний процесс наследует переменные окружения от своего родителя. Во-вторых, значение переменной окружения, установленное в дочернем процессе, родителю не видно.
ENV['alpha'] = '123'
ENV['beta'] = '456'
puts 'Родитель: alpha = #{env['alpha']}'
puts 'Родитель: beta = #(env['beta']}'
fork do # Код потомка...
x = ENV['alpha']
ENV['beta'] = '789'
y = ENV['beta']
puts ' Потомок: alpha = #{x}'
puts ' Потомок: beta = #{y}'
end
Process.wait
a = ENV['alpha']
b = ENV['beta']
puts 'Родитель: alpha = #{a}'
puts 'Родитель: beta = #{b}'
Программа выводит следующие строки:
Родитель: alpha = 123
Родитель: beta = 456
Потомок: alpha = 123
Потомок: beta = 789
Родитель: alpha = 123
Родитель: beta = 456
Это следствие того факта, что родитель ничего не знает о переменных окружения своих потомков. Поскольку программа на Ruby обычно исполняется в подоболочке, то после ее завершения все сделанные изменения переменных окружения не будут видны в текущей оболочке.
14.4.2. Хранение переменных окружения в виде массива или хэша
Важно понимать, что объект ENV
— не настоящий хэш, а лишь выглядит как таковой. Например, мы не можем вызвать для него метод invert
; будет возбуждено исключение NameError
, поскольку такого метода не существует. Причина такой реализации в том, что существует тесная связь между объектом ENV
и операционной системой; любое изменение хранящихся в нем значений отражается на состоянии ОС, а такое поведение с помощью простого хэша не смоделируешь.
Однако имеется метод to_hash
, который вернет настоящий хэш, отражающим текущее состояние:
envhash = ENV.to_hash
val2var = envhash.invert
Получив такой хэш, мы можем преобразовать его к любому другому виду (например, в массив):
envarr = ENV.to_hash.to_a
Обратное присваивание объекту ENV
недопустимо, но при необходимости можно пойти обходным путем:
envhash = env.to_hash
# Выполняем произвольные операции... и записываем обратно в ENV.
envhash.each {|k,v| ENV[k] = v }
14.4.3. Импорт переменных окружения как глобальных переменных
Существует библиотечка importenv.rb
, которая импортирует все переменные окружения, сопоставляя им глобальные переменные программы:
require 'importenv'
# Теперь переменные окружения стали глобальными переменными...