Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading in variables from a file in Ruby

Is there a way to read in a file of environment variables?

In bash I have a file env.sh that I can use

env.sh

foo="bar"

bash file

set -a
source env.sh

This would allow me to just use foo as if I had delcared it in the ruby script.

Also is it there a way to make sure that this file is unreadable so that passwords could be stored in this file?

like image 633
Tall Paul Avatar asked Aug 03 '13 05:08

Tall Paul


People also ask

How do I read data from a file in Ruby?

Opening a File in Ruby There are two methods which are widely used − the sysread(n) and the read() method. The open method is used to open the file, while the sysread(n) is used to read the first "n" characters from a file, and the read() method is used to read the entire file content.

How can you read an entire file and get each line in Ruby?

Use File#readlines to Read Lines of a File in Ruby File#readlines takes a filename to read and returns an array of lines. Newline character \n may be included in each line. We must be cautious when working with a large file, File#readlines will read all lines at once and load them into memory.

How do I view environment variables in Ruby?

Accessing Environment Variables from Ruby Ruby has direct access to environment variables via the ENV hash. Environment variables can be directly read or written to by using the index operator with a string argument.

How do you read a line by line in Ruby?

Overview. The IO instance is the basis for all input and output operations in Ruby. Using this instance, we can read a file and get its contents line by line using the foreach() method. This method takes the name of the file, and then a block which gives us access to each line of the contents of the file.


3 Answers

It sounds like you should provide a file example for the user/admin to modify for their personal environment, and then populate the environment from that, while avoiding, perhaps, having that file with the sensitive information in a repository. Note: per file security is going to be addressed by where the file is located and your operating system, and server software.

If this is the case, then you can provide a file that holds a template of the kind of things that you would require from the administrator/user of the program you are configuring.

Ruby has the ENV constant that acts like a Hash and holds the environment of the shell you are using.

As an example, there is a file called environment.rb.sample that gets shared with anyone, publicly. It has instructions and holds the template that users can modify freely, with instructions to copy the file to environment.rb. The sample file looks like this:

# environment.rb.sample
# Copy this file to environment.rb and change the name and password to your credentials
ENV['temp_user_name'] = 'Foo Bar'
ENV['temp_password'] = 'Dazz Kezz

The file is then copied to this, perhaps:

# environment.rb
ENV['temp_user_name'] = 'Joe Admin'
ENV['temp_password'] = 'Super Secure Password'

The file that loads this and uses it is just a Ruby file that is freely modified by the user/administrator of the software, and looks like this and is also shared publicly.

# load_environment
require './environment'
puts ENV['temp_user_name']
puts ENV['temp_password']

This loads the file and uses the ENV that is a globally scoped constant for the application.

The file permissions are then managed by the user/administrator of the system and secured like any other sensitive information on their system. The sensitive file should also be listed in the repository's ignore mechanism. It should never be made public.

like image 106
vgoff Avatar answered Oct 17 '22 20:10

vgoff


Yes, there is, and if for some bizzare, arcane reason you must use it, it's eval:

WARNING: Never use this on a user-supplied file

And, unless you have a very, very specific need, don't use it in production code.

eval(File.read("name_of_var_file"), binding)

If what you're really trying to do is write a configuration file, use YAML. A file like this:

config.yaml:

foo: "bar"

Can be accessed like this:

require 'yaml'
conf = YAML.loads(File.read("config.yaml"))
conf['foo'] #=> 'bar'

This is secure and manageable, not to mention standard practice.


As for making the file inaccessible, that is an operating system level problem that can't be solved without information on the environment, OS, setup, etc.

like image 34
Linuxios Avatar answered Oct 17 '22 21:10

Linuxios


The purpose of a local variable is to be used temporally within a method definition or a block. Using it outside of such environments, particularly across files defeats the purpose of it. You should not need to do it, and Ruby does not have a simple way to do it.

If you are using variables correctly, and want to share variables between files, that should be other types of variables such as instance, class, or global variables. Or, for the purpose of setting environments, you should be using constants. Among them, global variables and constants can be written in a file, loaded in a different file, and be used.

file-a.rb

$foo = 1
FOO = 2

file-b.rb

load "file-a.rb"
$foo # => 1
FOO # => 2

As for instance and class variables, they belong to a class or an instance of it, so they should be defined in such environment. And you can reopen the same class within a different file, and load it in another file.

file-a.rb

class Bar
  @@foo = 1
  def initialize; @foo = 2 end
end

file-b.rb

load "file-a.rb"
Bar.class_variable_get("@@foo") # => 1
Bar.new.instance_variable_get("@foo") # => 2
like image 2
sawa Avatar answered Oct 17 '22 20:10

sawa