2

I am writing an installation script in bash that will be run as root upon provisioning a new server. It will install rbenv for the deploy user and install some default rubies/gems. My script is complete to the point of setting up rbenv, but it cannot install rubies as the deploy user. I know that rbenv is set up correctly because when I SSH as the deploy user I have access to rbenv like usual. Here's what I have so far:

# install rbenv
git clone https://github.com/sstephenson/rbenv.git /home/deploy/.rbenv

# install ruby-build and auto-rehash plugins
git clone https://github.com/sstephenson/ruby-build.git /home/deploy/.rbenv/plugins/ruby-build
git clone https://github.com/sstephenson/rbenv-gem-rehash.git /home/deploy/.rbenv/plugins/rbenv-gem-rehash

# fix permissions since we've been running as root
chown -R deploy:deploy /home/deploy/.rbenv

# setup rbenv
echo "export PATH=\"~/.rbenv/shims:~/.rbenv/bin:$PATH\"" >> /home/deploy/.bashrc
echo 'eval "$(rbenv init -)"' >> /home/deploy/.bashrc

# now install default ruby
sudo -i -u deploy /bin/bash - <<-EOF
    rbenv install $ruby_version
    rbenv global $ruby_version
    echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
    gem install bundler
EOF

I have tried every combination of -i, -H, -l that I can think of but I keep getting:

/bin/bash: rbenv: command not found

What am I doing wrong?

Andrew
  • 227,796
  • 193
  • 515
  • 708
  • [This](http://stackoverflow.com/a/19074129/2235132) might help. – devnull Dec 12 '13 at 06:51
  • @devnull thanks, but that's not the issue. Permissions are already correct. – Andrew Dec 12 '13 at 06:55
  • I've added my setup steps to prove it. – Andrew Dec 12 '13 at 06:58
  • `sudo -i` would simulate the login shell. In that event, `~/.bashrc` wouldn't be read; try adding the variables to `~/.profile` or `~/.login` instead. – devnull Dec 12 '13 at 07:08
  • @devnull The [rbenv readme explicitly says to add it to `~/.bashrc` on Ubuntu](https://github.com/sstephenson/rbenv#basic-github-checkout). Wouldn't that change the normal use of rbenv? – Andrew Dec 12 '13 at 18:18

3 Answers3

3

Take a look at top of your ~/.bashrc. Probably you'll find this chunk of code:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

That means, that bashrc returns if it's not running interactively.

Thus, sudo -i -u deploy /bin/bash -i - <<-EOF should work like a charm

Kukunin
  • 853
  • 7
  • 22
0

If rbenv is installed and you receive a command not found error, that means that you likely have a PATH problem. You put the necessary PATH into the deploy user's ~/.bashrc file. However, bash only guarantees to read ~/.bashrc when the shell is both interactive and non-login. I would suggest either putting the PATH statement in a script that is read or, possible easier, provide explicit paths in your here script.

When invoked as a login shell (as per sudo -i), bash will read /etc/profile, if it exists. and then it will read the first file it finds (and only the first) from the list: ~/.bash_profile, ~/.bash_login, and ~/.profile.

As a final note, the ~/.bashrc file that is created by the script is owned by root. You might want to make sure that your user has permission to read it or else give him ownership via chown as you do for his ~/.rbenv files.

John1024
  • 109,961
  • 14
  • 137
  • 171
  • Thanks. The loading of the various bash scripts is a little more clear now. However, the rbenv readme explicitly says to add it to ~/.bashrc on Ubuntu. Would moving the init code to `~/.bash_profile` change the normal use of rbenv? – Andrew Dec 12 '13 at 18:20
  • Also, I think the `~/.bashrc` file is created when the user is created because it is already has the correct ownership. – Andrew Dec 12 '13 at 18:22
  • I also just noticed that there is a `~/.profile` that contains code to load `~/.bashrc` if it exists, so it shouldn't matter if it's a login/non-login shell, right? – Andrew Dec 12 '13 at 18:34
  • I tried adding the `export PATH` part before my `rbenv` commands and it worked. I tried manually sourcing my `.bashrc` but that didn't work. I don't understand why. – Andrew Dec 12 '13 at 18:47
  • Glad you got it working. If `~/.profile` sources `~/.bashrc`, then that should work for login-shells but only if `~/.bash_profile`, and `~/.bash_login` do _not_ exist or, if they do exist, check to be sure that they also source `~/.bashrc`. As for the other point, before I would guess why manually sourcing `~/.bashrc` didn't work but exporting PATH did (they should be the same), I would want to see the full script, the complete .bashrc and the full error messages. Regards, – John1024 Dec 12 '13 at 22:20
0

I had this same issue whilst trying to install ruby-2.2.3 with rbenv using Ansible 2.1 on a vagrant box.

rbenv was installed on a user on ubuntu called rails but when ansible connects to my ubuntu box, it looses the env. $PATH defined in /home/rails/.bashrc it was defaulting to just the ansible_env.PATH

Assuming you have installed rbenv following these steps:

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

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

to get the path working, I needed to set it manually, so for that particular task I did:

- name: install rubies
  become_user: rails
  environment: 
    PATH: "{{ ansible_env.PATH }}:/home/rails/.rbenv/shims:/home/rails/.rbenv/bin "
  shell: '{{ rbenv_shell }} -lc "rbenv install {{ item[0] }}"'
  ...

This will append the path to your rbenv command to ansible_env.PATH lookup and get it working as expected.

Kingsley Ijomah
  • 3,273
  • 33
  • 25