Deploy a Shell Script with Ruby Gem and Install in Bin Directory

Is it possible to use gems to deploy non-ruby executables?

After some digging, I found that the answer is "almost". It can work if one installs the gem with --no-wrapper then all executables will be added with no wrappers to the bin dir. It's kind of unpleasant, but it works.

Relevant issue: https://github.com/rubygems/rubygems/issues/88

Another question (basically the same as this): Deploy a shell script with Ruby gem and install in bin directory

Add a Ruby command-line application to /usr/bin?

First, add a "she-bang" string as first line of your file. It will allow the shell to run the file. It should be:

#!/usr/bin/env ruby

Then give execution permissions to the file:

$ chmod +x your_file_name.rb

Now you can run your application:

./your_file_name.rb

Also you can add the path to the directory with this script to the PATH variable and run the application from anywhere you want.

# You may do this in ~/.bashrc file
PATH=$PATH:path/to/dir/with/script/

Install gem from ruby script and use it afterwards

After all, I solved the problem digging into gemianbox gem - it seems it uploads gem with a simple POST request, so gem inabox command isn't necessary at all, uploading can be achieved with a simple CURL command:

curl -F 'file=@/some/file.gem' https://some.host/upload

Ruby: 'bundle exec' throws error for all shell commands

Ok, finally after two days, I was able to make it work.

bundle install installs my GEM and creates a ruby wrapper by default to sh files in the 'bin' directory. So, when I call my script using bundle exec the ruby wrapper gets called first and it calls my script using a ruby 'load' function. This load function expects a ruby file and that is why all my shell script in the file threw errors, because they were expected to be in ruby.

A workaround to this is installing my gem before 'bundle install' using the following command:

gem install --no-wrapper my-gem

Apparently this command disabled creating the ruby wrapper and I was finally able to call the script using bundle execute do_something.sh

How to deploy Rails app and install Ruby Native Extension in user directory

I think what you're looking for is ruby version manager (rvm). It's available here and allows you to manage versions of Ruby, Rails, and Gem sets.

https://rvm.io/

There's a good getting started guide here as well: http://rvm.beginrescueend.com/rvm/install/

Here's how the install goes:

[sam@mungr ~]$ \curl -L https://get.rvm.io | bash -s stable --ruby
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 10956 100 10956 0 0 2240 0 0:00:04 0:00:04 --:--:-- 2240
Please read and follow further instructions.
Press ENTER to continue.
Downloading RVM from wayneeseguin branch stable
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1243k 100 1243k 0 0 570k 0 0:00:02 0:00:02 --:--:-- 929k

Installing RVM to /home/sam/.rvm/
Adding rvm PATH line to /home/sam/.bashrc /home/sam/.zshrc.
Adding rvm loading line to /home/sam/.bash_profile /home/sam/.zprofile.

# RVM: Shell scripts enabling management of multiple ruby environments.
# RTFM: https://rvm.io/
# HELP: http://webchat.freenode.net/?channels=rvm (#rvm on irc.freenode.net)
# Cheatsheet: http://cheat.errtheblog.com/s/rvm/
# Screencast: http://screencasts.org/episodes/how-to-use-rvm

# In case of any issues read output of 'rvm requirements' and/or 'rvm notes'

Installation of RVM in /home/sam/.rvm/ is almost complete:

* To start using RVM you need to run `source /home/sam/.rvm/scripts/rvm`
in all your open shell windows, in rare cases you need to reopen all shell windows.

# sam,
#
# Thank you for using RVM!
# I sincerely hope that RVM helps to make your life easier and
# more enjoyable!!!
#
# ~Wayne

rvm 1.17.7 (stable) by Wayne E. Seguin <wayneeseguin@gmail.com>, Michal Papis <mpapis@gmail.com> [https://rvm.io/]

No binary rubies available for: downloads/ruby-1.9.3-p362.
Continuing with compilation. Please read 'rvm mount' to get more information on binary rubies.
Fetching yaml-0.1.4.tar.gz to /home/sam/.rvm/archives
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 460k 100 460k 0 0 342k 0 0:00:01 0:00:01 --:--:-- 492k
Extracting yaml to /home/sam/.rvm/src/yaml-0.1.4
Configuring yaml in /home/sam/.rvm/src/yaml-0.1.4.
Compiling yaml in /home/sam/.rvm/src/yaml-0.1.4.
Installing yaml to /home/sam/.rvm/usr
Installing Ruby from source to: /home/sam/.rvm/rubies/ruby-1.9.3-p362, this may take a while depending on your cpu(s)...
ruby-1.9.3-p362 - #downloading ruby-1.9.3-p362, this may take a while depending on your connection...
ruby-1.9.3-p362 - #extracting ruby-1.9.3-p362 to /home/sam/.rvm/src/ruby-1.9.3-p362
ruby-1.9.3-p362 - #extracted to /home/sam/.rvm/src/ruby-1.9.3-p362
ruby-1.9.3-p362 - #configuring
ruby-1.9.3-p362 - #compiling
ruby-1.9.3-p362 - #installing
Retrieving rubygems-1.8.24
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 371k 100 371k 0 0 430k 0 --:--:-- --:--:-- --:--:-- 611k
Extracting rubygems-1.8.24 ...
Removing old Rubygems files...
Installing rubygems-1.8.24 for ruby-1.9.3-p362 ...
Installation of rubygems completed successfully.
Saving wrappers to '/home/sam/.rvm/bin'.
ruby-1.9.3-p362 - #adjusting #shebangs for (gem irb erb ri rdoc testrb rake).
ruby-1.9.3-p362 - #importing default gemsets (/home/sam/.rvm/gemsets/), this may take time ...
Install of ruby-1.9.3-p362 - #complete
Creating alias default for ruby-1.9.3-p362.
Recording alias default for ruby-1.9.3-p362.
Creating default links/files
Saving wrappers to '/home/sam/.rvm/bin'.

* To start using RVM you need to run `source /home/sam/.rvm/scripts/rvm`
in all your open shell windows, in rare cases you need to reopen all shell windows.

Once complete I've got a fully functional install of Ruby 1.9.3-p362:

[sam@mungr ~]$ source /home/sam/.rvm/scripts/rvm
[sam@mungr ~]$ rvm list

rvm rubies

=* ruby-1.9.3-p362 [ x86_64 ]

# => - current
# =* - current && default
# * - default

Which version of Ruby?

[sam@mungr ~]$ which ruby
~/.rvm/rubies/ruby-1.9.3-p362/bin/ruby

A little Hello World

[sam@mungr ~]$ ruby -e "puts 'Hello world'"
Hello world

EDIT #1

Through the course of discussing this question the author, Crivens, noted that he was getting the following error:

Error curl: (77) Problem with the SSL CA cert (path? access rights?)
and OS is Linux version 2.6.32-042stab055.16 (root@rh6-build-x64) (gcc
version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) ) #1 SMP Fri Jun 8
19:22:28 MSD 2012. I'm still hoping to use the system install of ruby.

If you encounter this error it usually means one of two things:

1. I think you're just missing this RPM, ca-certificates-2010.63-3.el6. These are the certificates. My install of RVM on a Ubuntu 8.04.4 machine fails. Should I install it as multi-user instead?

solution #1

% yum install ca-certificates-2010.63-3.el6

2. The developer for rvm, Wayne, changed the URL from rvm.beginrescueend.com to rvm.io and probably wonked the SSL certs. Curl Certificate Error when Using RVM to install Ruby 1.9.2

solution #2

% curl -L get.rvm.io | bash -s stable

-or-

% echo insecure > ~/.curlrc

Running RubyGem CLI during development

Normally when you run an executable from a gem Rubygems will set up the LOAD_PATH for you so that it contains your gems’ lib directory. Obviously when you run the script in development Rubygems doesn’t get the chance to set things up for you so you will need to do it yourself.

One way to do this is in the script file itself. For example the Haml and Redcarpet gems do this. Somewhere near the top of your executable you would have something like this:

$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'

(assuming a fairly typical directory layout).

Another way, if you want to avoid manipulating the load path in code, would be to add the lib dir in the command line. The -I option to the ruby command lets you do this, so you could run:

$ ruby -Ilib/ bin/roar

from the top level of your gem.

Alternatively you could use the RUBYLIB environment variable:

$ RUBYLIB=lib ruby bin/roar

or even (if bin/roar has a shebang line and is executable):

$ RUBYLIB=lib ./bin/roar

You could even export RUBYLIB so you didn’t need to specify it each time, but you would need to be careful about leaving it set if you did that.

You don't have write permissions for the /var/lib/gems/2.3.0 directory

You first need to uninstall the ruby installed by Ubuntu with something like sudo apt-get remove ruby.

Then reinstall ruby using rbenv and ruby-build according to their docs:

cd $HOME
sudo apt-get update
sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libxml2-dev libxslt1-dev libcurl4-openssl-dev libffi-dev

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL

rbenv install 2.3.1
rbenv global 2.3.1
ruby -v

The last step is to install Bundler:

gem install bundler
rbenv rehash

How do I use gems with Ubuntu?

Where are my Gems?

You can find where your gems are stored using the gem environment command. For example:

chris@chris-laptop:~$ gem environment
RubyGems Environment:
- RUBYGEMS VERSION: 1.3.2

- RUBY VERSION: 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
- INSTALLATION DIRECTORY: /usr/lib/ruby/gems/1.8
- RUBY EXECUTABLE: /usr/bin/ruby1.8
- EXECUTABLE DIRECTORY: /usr/bin
- RUBYGEMS PLATFORMS:
- ruby
- x86-linux
- GEM PATHS:
- /usr/lib/ruby/gems/1.8
- /home/chris/.gem/ruby/1.8
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:

If you look at the "GEM PATHS:" section you can see that gems can be stored in two places on my laptop: /usr/lib/ruby/gems/1.8 or in the .gem directory in my home dir.

You can also see that executables are stored in EXECUTABLE DIRECTORY which in this case is /usr/bin.

Because /usr/bin is in my path this lets me run cap, merb, rails etc.

Updating your PATH

If for some reason your EXECUTABLE DIRECTORY isn't on your path (for example if it is /var/lib/gems/1.8/bin) then you need to update your PATH variable.

Assuming that you are using the bash shell. You can do this quickly for the current session by typing the following at the shell prompt; let's pretend that you want to add /var/lib/gems/1.8/bin to the path:

export PATH=$PATH:/var/lib/gems/1.8/bin

and press return. That appends the new directory to the end of the current path. Note the colon between $PATH and /var/lib/gems/1.8/bin

To set the value for all sessions you will need to edit either your .profile or .bashrc file and add the same line to the end of the file. I usually edit my .bashrc file for no reason other than that's what I've always done. When finished, save the file and then refresh your environment by typing:

bash

at the shell prompt. That will cause the .bashrc to get reread.

At any point you can check the current value of $PATH by typing

echo $PATH

at the shell prompt.

Here's a sample from one of my own servers, where my username is "chris" and the machine name is "chris-laptop":

chris@chris-laptop:~$ 
chris@chris-laptop:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
chris@chris-laptop:~$
chris@chris-laptop:~$ export PATH=$PATH:/var/lib/gems/1.8/bin
chris@chris-laptop:~$
chris@chris-laptop:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/var/lib/gems/1.8/bin
chris@chris-laptop:~$

My Gem won't load!

"Ruby gems won't load even though installed" highlights a common problem using multiple different versions of Ruby; Sometimes the Gem environment and Gem path get out of sync:

rb(main):003:0> Gem.path

=> ["/opt/ruby1.9/lib/ruby1.9/gems/1.9.1"]
irb(main):004:0> exit

Any Ruby process here is looking only in one place for its Gems.

:~/$ gem env
RubyGems Environment:
- RUBYGEMS VERSION: 1.3.7
- RUBY VERSION: 1.9.1 (2009-05-12 patchlevel 129) [x86_64-linux]
- INSTALLATION DIRECTORY: /opt/ruby1.9/lib/ruby/gems/1.9.1
- RUBY EXECUTABLE: /opt/ruby1.9/bin/ruby1.9
- EXECUTABLE DIRECTORY: /opt/ruby1.9/bin
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-linux
- GEM PATHS:
- /opt/ruby1.9/lib/ruby/gems/1.9.1
- /home/mark/.gem/ruby/1.9.1
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :benchmark => false
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- http://rubygems.org/

Look carefully at the output of gem environment:

  - GEM PATHS:
- /opt/ruby1.9/lib/ruby/gems/1.9.1

This isn't the same path as returned by Gem.path:

["/opt/ruby1.9/lib/ruby1.9/gems/1.9.1"]

It's hard to say what exactly caused lib/ruby to change to lib/ruby1.9 but most likely the developer was working with multiple Ruby versions. A quick mv or ln will solve the problem.

If you do need to work with multiple Ruby versions then you really should be using rvm.



Related Topics



Leave a reply



Submit