How to change /usr/bin/env? - ruby

I have scripts that use #!/usr/bin/env ruby but I've switched to using Ruby Enterprise Edition instead of the default ruby that is included with Ubuntu server. Thus, the scripts freak out when I try to run them. How can I add the Ruby EE path to /usr/bin/env?

#!/usr/bin/env ruby is similar to simply calling ruby from the command line, so the same rules apply. Basically, the individual entries in the $PATH environment variable are checked in order, and the ruby that is found first is used. So make sure that the ruby for Ruby EE is earlier in the search path order than your other rubys.
I'm not familiar with Ruby EE, so if it doesn't have an executable called ruby, just create a symlink in a directory that's early in your search path to Ruby EE's executable.

Since you have an explicit dependency on Ruby EE, you could always modify the scripts instead of your environment ( which could have other unintended consequences ).
#!/usr/bin/env ruby
becomes
#!/path/to/enterprise/edition/ruby
Now it becomes clear to the reader that you using a specific version of ruby rather than just whatever ruby is in your path.

I had a similar problem where cron jobs stopped working... Cron seems to run commands by default without using the PATH settings you would expect for the user (when logging in as that user). In fact it didn't even seem to use any of the default PATH settings (be it in /etc/profile or elsewhere).
I was able to find the problem using the following commands (the first one is how cron seems to run commands):
su -c 'printenv PATH' userX
With output: /usr/local/bin:/usr/bin:/bin:/usr/games
su -l userX -c 'printenv PATH'
With output: /opt/ruby-enterprise-1.8.7-2010.02/bin/:/opt/ruby-enterprise-1.8.7-2010.02/bin/:/usr/local/bin:/usr/bin:/bin:/usr/games
The first command doesn't seem to populate the PATH variable in any way except for the bare system default.
In my case I solved it by just adding the necessary (REE) path to: /etc/login.defs, which by default looks as follows:
/etc/login.defs:103:ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/games

See section 1.6 in the Ruby EE documentation page:
http://www.rubyenterpriseedition.com/documentation.html
For a system wide change you can update your PATH in the /etc/environment file to include the Ruby EE bin directory. Maybe something like this:
PATH="/opt/ruby-enterprise-x.x.x/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
If you only want to the change to be visible for one user on the system you can update your .bashrc or .profile with the correct path.
Make sure to include the REE path first in the list of directories.

I posted the solution I used on Ubuntu here:
http://groups.google.com/group/emm-ruby/browse_thread/thread/d0c685bbd096823a#msg_effa7d6ad42c541c
There were some additional steps to get it working beyond what was described in the Ruby Enterprise Edition documentation.

Related

error Your Ruby version is 2.6.8, but your Gemfile specified 2.7.5

This happens when I run npx react-native init AwesomeProject.
When I check the system ruby version with ruby -v, it is already 2.7.5. ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-darwin21]. Anyone has any idea for this problem?
Sounds like you’re using rvm to manage Ruby versions.
You need to install and run the correct version, not delete the current.
Something like
rvm install 2.7.5
rvm use 2.7.5
The Gemfile Isn't (Directly) Your Issue
The Gemfile is irrelevant to solving this issue. It's just triggering it because your in-project Ruby version isn't matching what RubyGems (via the Gemfile or Gemfile.lock) expects as a constraint. It could be a minimum version, an exact version, an approximate version, and so forth. There are a lot of ways to specify version constraints in a project, and the Gemfile is just where the constraint-related exception is being raised by Bundler.
You could possibly make the problem go away simply by removing the requirement for a later version of Ruby from the Gemfile or gemspec, removing the Gemfile.lock, and re-running Bundler. However, if your code relies on features in a later version this will just create other problems for you. You really ought to uncover what's changing your Ruby environment within the project directory.
Dotfiles
There are a lot of reasons this could happen, but if your system Ruby is 2.7.5, then you need to check your project directory for various dotfiles like:
.ruby-version
.rvmrc
~/.rvmrc
.envrc
.env
or various other files that affect your shell environment or whatever Ruby version manager you're using. Most Ruby version managers respect .ruby-version, but some version managers use other files, including defaults or shims that may be set elsewhere. IDE's also often have their own project-specific configuration files, too, and they can sometimes be set to override the project's standard settings.
Also, make sure to check your Gemfile.lock and *.gemspec in addition to the Gemfile itself, in case something is being specified there or constrained by some other dependency.
Inspecting Environment Variables
You should also look at the Ruby- and RubyGems-related environment variables from your project directory to see how various values are set within the project. For example:
printenv | grep -E '^(RUBY|GEM)' | sort
Shebang Lines
In addition, you should check your shebang lines in any executable Ruby or shell scripts you're relying on to see whether a specific non-system Ruby is being invoked. For example:
grep -Enr '^#.*ruby' *.rb | grep -F '.rb:1:'
will find all the shebang lines that properly appear on the first line of a Ruby file. This will either point to a specific Ruby like #!/usr/bin/ruby or might be using a PATH lookup with #!/usr/bin/env ruby.
Shell scripts might be harder to inspect, as there may be calls to other executables or even an exec command, so you'll need to be more liberal with your grepping if you are looking for an interpreter call further down than the shebang line.
Checking PATH Order
In the case of #!/usr/bin/env ruby, you should inspect your PATH environment variable to see why the Ruby you want isn't being called first. Using which -a ruby (if supported by your OS) will show you all rubies in your PATH in the order they would be invoked by the shell. It's possible that you're simply calling an unexpected Ruby version that comes first in the PATH.

Activate/deactivate conda virtualenvs on entering/leaving directories

pyenv-virtualenv offers a nice way of activating the environment on the very instant of entering or leaving the directory which contains a .python-version text file which specifies the environment to activate. It works for the directory it is in and all directories contained in it.
The environment is deactivated once we change the directory to something above it. This allows to easily switch between projects or analyses using different python versions (just by changing the directories).
Is there a way of achieving the same behaviour with (ana)conda?
Edit: added bash tag, because - as far as I understand - pyenv achieves this by hooking a custom script into .bashrc (which allows it to monitor the directory changes). If there is no build-in way in conda, how to create a script which would make it possible?
As mentioned in my comment, this is currently not supported. There is however an open issue on conda's GitHub asking for this feature.
In the meantime you could use autoenv, a small tool that'll automatically run the code in a .env file when entering a directory and that in a .env.leave when leaving the directory (supports bash/zsh and a couple others).
A simple example taken from their readme which illustrates the feature quite nicely:
$ echo "echo 'whoa'" > project/.env
$ cd project
whoa
To load a conda environment your .env would simply look like this:
conda activate <my_env>
Note 1: Check out the Configuration section of their GitHub readme before you start using it.
Note 2: The author of autoenv actually suggests trying direnv instead. However I've never used it, so I can't comment on it.
From autoenv's readme:
you should probably use direnv instead. Simply put, it is higher quality software. But, autoenv is still great, too. Maybe try both? :)

What is the difference between activating an anaconda environment and running its python executable directly?

I have setup multiple python environment using Anaconda.
Usually, to run a script "manually", I would open a command line and then type:
activate my-env
python path/to/my/script.py
Fine.
Now I am trying to run a script automatically using a scheduler and I was wondering what the difference was between
Writing a batch which activates the environment and the executes the script (like in the snippet above)
Calling directly the python executable from the environment (within the envs/my-enjv/ directory) like below:
/path/to/envs/my-env/python.exe path/to/my/script.py
Both seem to work fine. Is there any difference?
I don't claim to be an expert but here's my 2 cents.
For small scripts, no, there isn't a difference.
You should notice a difference when calling external modules / packages. conda activate alters the system path to change how the command shell searches for the appropriate capabilities.
If you supply a full path to an interpreter and the full path to an isolated script, then the shell doesn't need to do a lookup as this has priority over the path. This means you could be in a situation where the interpreter can see the script but cannot see dependencies.
If you follow the conda activate process, and the environment is correctly packaged, then the shell will be able to trace any additional resources.
EDIT: The idea behind this is portability. If an admin has been careful in setting up a system, then scripts should have the appropriate visibility - i.e. see everything in it's environment plus everything in the main system installation.
It's possible to full-path every call to an interpreter and a script or package location, but then what happens when you need to move it to another machine? You would need to spend a lot of time setting everything up exactly as it was before. On the other hand, you can follow the package process and the system path will trace everything for you.
Simply checkout the PATH variable in your environment. After conda activation it has been extended by
\Anaconda3;
\Anaconda3\Library\mingw-w64\bin;
\Anaconda3\Library\usr\bin;
\Anaconda3\Library\bin;
\Anaconda3\Scripts;
\Anaconda3\bin;
This doesn't make much of a difference, if you are just using the standard library in your code. However, if you rely on external packages like pandas, it's a prerequisite so that the modules can be found.

How to control what Ruby interpreter Puppet uses?

I have an app that requires Ruby 2.1 and use Puppet to provision a handful of servers.
The problem is, when I install on the 2.1 version of Ruby, Puppet starts using that, and it is not supported.
I would like to somehow point Puppet to a 2.0 version of Ruby installed in /opt.
Any suggestions?
Perhaps you could add a shebang line in the .rb file that points to the other version of ruby?
Alternatively you could try to specifically add the bin/ruby location in /opt to the $PATH variable.
Typically, you shouldn't let the system determine the path, but instead provide the full path to the Ruby interpreter you want to execute your script:
/usr/bin/ruby /some/path/to/foo.rb
Or:
/usr/local/bin/ruby1.9.2 /path/to/bar.rb

Is it possible Ruby installation by copying the ruby folder?

This is a very silly question...
I have a doubt regarding the ruby installation. Will the ruby be installed in a windows server if we copy the Ruby187 folder from another server and add that in the PATH of the environment variable?
Or Do we need to install the Ruby from the installer always, in order to install it ?
Thanks in advance
I actually did something similar to this yesterday at work. A fellow co-worker, who does not have Ruby installed on their system, needs the ability to run my scripts while I am on vacation. So, I copied the entire Ruby folder from my C: to a shared network drive.
You will not only have to add the path to the Ruby folder to your PATH variable but you also may want to associate the Ruby extension .rb with Ruby. Not needed but just a thought.
One issue I ran into was here at work we don't have permission to alter our PATH variable manually. So, in order for my co-worker to launch the scripts I needed ran, I wrote a small C++ app that merely run a command line call to the Ruby interpreter and then to the script to run.
So, in short, yes, it is possible. =)
EDIT: In regards to why you would add the path to the Ruby installation to the PATH variable, it is so you can call Ruby from the command line with simply C:\>ruby some_script.rb. Without that added to your PATH, you'd need to type the entire path every time like C:\>C:\ruby192\bin\ruby some_script.rb. However, you'd still need to type "ruby" first.
In regards to the association of ".rb" files to the Ruby Interpreter, it is an option while installing Ruby on Windows using the installer provided at ruby-lang.org. With that, you would not need to type "ruby" before the script name on the command line. C:\>some_script.rb would work. I don't know exactly how to do this with a network version of Ruby but one way might be to right-click on a ".rb" file, choose "Open with..." and locate the Ruby.exe file in \ruby192\bin\ruby.exe.
I hope that explains what you were asking about in the comments.

Resources