Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

shebang for multiple versions

In my large collection of Ruby scripts, I do start my scripts with the common shebang:

#!/usr/bin/env ruby

Now I am finding some scripts that do need certain Ruby version, and no, they are no Rails apps that can be deployed under a specific Ruby version. They are just single file scripts that can be launched from the command line and fail to work with the system version.

Is there any way to write a shebang that sets the environment with rbenv/rvm before running the following code of the file?

like image 432
SystematicFrank Avatar asked Nov 25 '13 21:11

SystematicFrank


2 Answers

You don't necessarily need to set up any environment. All you need is the path to the ruby binary you want to run and everything else will follow.

Here's an example on how you could set it up:

  1. Create a folder ~/bin. This will hold pointers (symlinks) to all your personal ruby binaries.

  2. Update your shell PATH so that ~/bin is included in the search path for executables.

  3. Symlink any ruby binary you need in your ~/bin to the actual ruby binary.

For example in my ~/bin I have:

ruby18 -> /opt/ruby18/bin/ruby
ruby19 -> /opt/ruby19/bin/ruby
ruby20 -> /opt/ruby20/bin/ruby

Now let's say you have a script which needs 1.9 to run. Then all you need to do is:

#!/usr/bin/env ruby19

This will work if you have installed your gems into the default gem directory for each ruby executable. If you have installed gems somewhere else then it gets more complicated and you would need to modify GEM_PATH before you run your script.

If you don't want to get fancy with ~/bin then just hardcode your shebang line instead to point directly to the ruby binary:

#!/opt/ruby19/bin/ruby

...or the equivalent rbenv/rvm path.

Having symlinks in your ~/bin though will allow you to more easily update your bin pointers if let's say you compile a new patch of ruby 1.9, and you want to place it in another folder like /opt/ruby19-p123. Then you just need to update the symlink in ~/bin and all your scripts will run the new patched version.

like image 102
Casper Avatar answered Sep 18 '22 02:09

Casper


rbenv will look for the .ruby-version file set by (for example)

$ rbenv local 1.9.3-p448

Create a simple file, check

#!/usr/bin/env ruby
puts RUBY_VERSION

Make it executable

$ chmod +x check

Run it

$ ./check

Output

1.9.3

That said, this is not a per-file setting. If there's a way to alter rbenv's behavior using the shebang, that would probably be a better fit.

like image 41
maček Avatar answered Sep 19 '22 02:09

maček