0

I am trying to get Ruby on Rails set up on my laptop.
I ran through the guide here: http://elinux.org/RPi_Ruby_on_Rails

Everything seemed fine, but when I went to run a Rails server while using LXTerminal in the GUI, I got an error after I simply typed in rails -v:

bash: rails: command not found

Although while i'm in the terminal and do the same I get:

Rails 4.0.3

Basically a proper response

Is there something I can do to fix this? I develop much better in a graphical environment with syntax highlighting and all that jazz

UPDATE:

When i do whereis rails:

rails:

The echo $PATH in the GUI is this:

/usr/lib/arm-linux-gnueabihf/libfm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/pi/.rvm/bin:/home/pi/.rvm/bin

and in the basic console is this:

/home/pi/.rvm/gems/ruby-2.1.1/bin:/home/pi/.rvm/gems/ruby-2.1.1@global/bin:/home/pi/.rvm/rubies/ruby-2.1.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/pi/.rvm/bin
Funkyguy
  • 200
  • 3
  • 12
  • Post the output of whereis rails from the first case, and the output of echo $PATH in both cases. – goldilocks Mar 11 '14 at 22:34
  • Updated! seems odd that the path would be different between the two – Funkyguy Mar 11 '14 at 22:55
  • I've put the explanation in an answer, but I'd also like to point out that raspbian has a package for RonR 2.3 and 3.2 (look at apt-cache search ruby | grep rails) in case you are unaware; I'm going to try and add a note to that elinux page about this. – goldilocks Mar 12 '14 at 00:10
  • if I wanted to install the newer versions, would I just run through the guide that I linked in my original question and just substitute for the new versions or is there a different process? – Funkyguy Mar 12 '14 at 00:12
  • You just install them: apt-get install ruby-rails-3.2. This will pull in any pre-reqs. That will be a system wide installation so it won't overwrite the stuff in /home. You might as well leave that for the moment, but remove any reference to it from $PATH in ~/.profile and login again to make sure your current path is cleared. If the distro version works out (presumably it will), you can then just delete all the stuff in /home/pi. – goldilocks Mar 12 '14 at 00:24
  • Whoops! Just caught a bad cut n' paste typo in the apt-get command from that last comment. Corrected now ;) It should read apt-get install ruby-rails-3.2. – goldilocks Mar 12 '14 at 00:28
  • haha okay! I might just re-flash my os and start over since I wasn't able to get ssh working either for some reason – Funkyguy Mar 12 '14 at 00:29
  • Tch. That's the absolute worst way to solve a problem! This is no big deal. If you are having problems w/ ssh, just ask more questions. Note that general linux stuff is better off on the Unix & Linux board; unless you are sure something is really peculiar to the pi, ask there. – goldilocks Mar 12 '14 at 00:31
  • Okay! thats kind of the thing, I don't know whether something is rasbian or general linux – Funkyguy Mar 12 '14 at 00:34
  • Raspbian is stock Debian compiled for the pi's architecture with some appropriate default configuration options (using lightdm as the default dm is one of those), so if it involves the OS, it's almost certainly a general linux question. Pi specific things would be mostly about the electronics, or software that is written exclusively for the pi, which are few in number and usually explicitly obvious (wiringPi, python modules like RPIO, etc.). – goldilocks Mar 12 '14 at 00:47

1 Answers1

1

This is because of lightdm, the default display manager you use to do a GUI login on raspbian.

Personal additions to $PATH are usually set in ~/.profile. This is a file bash reads when invoked as a login shell. Login shells include those where you must explicitly log in with your user name and password (e.g., the non-GUI console -- for future reference, that's referred to as a VT for "virtual console") and those used in ssh sessions.

You can also invoke a login shell with bash --login, which since you are already logged in will not prompt you, but it does start a new shell that will read .profile. This is not obvious (nothing appears to happen) but if you then run exit you'll notice your terminal doesn't close (instead, you've closed the shell you just started inside the first shell).

Environment variables like $PATH are inherited. In other words, if you export FOO=bar, all the subsequently created children of that shell will inherit it. However, it does not affect anything else. For example, if you have two GUI terminals open, the other terminal will not know about $FOO.

The reason .profile is used for $PATH is that the other file commonly used to set variables and so on for bash is ~/.bashrc, and that file is read for every non-login interactive shell (it's also usually sourced by .profile, so ends up applied to login shells too). The reason .bashrc is not used is that adding to $PATH means doing this (e.g.):

PATH=/foo/bar/bin:$PATH

Now $PATH will be what it was before, with the /foo/bar/bin stuff prepended. If that were in .bashrc, which is run for every new shell which has inherited $PATH from its parent, you can end up prepending that an arbitrary number of times so your path starts:

/foo/bar/bin:/foo/bar/bin:/foo/bar/bin...

Etc.

Here's the problem: a GUI display manager logs you in, but it's not a shell, so ~/.profile is not automatically sourced. And once you're logged in, the shells you start are not login shells. Most display managers compensate for this by sourcing ~.profile anyway, but the designers of lightdm made the strange decision not to do this, you can find their justification here. Note they have a suggested solution involving X session files, which will work, but I'm going to suggest something a little more thorough.

Now you're aware of this (look in ~/.profile, you'll see the addition made by the RonR installer), you can either use bash --login, meaning your access to rails will be limited to that shell and its children, or you can apply a trick in ~/.bashrc to append to path only when /foo/bar/whatever is not already there. Here's two bash functions, the first will prepend a string if it's not in $PATH already, the second appends:

# Prepend to $PATH
prependToPath () {
        for a; do
                echo $PATH | grep -q $a
                if [ $? != 0 ]; then
                        PATH=$a:$PATH
                fi
        done
        export PATH
}

# Append to $PATH
appendToPath () {
        for a; do
                echo $PATH | grep -q $a
                if [ $? != 0 ]; then
                        PATH=$PATH:$a
                fi
        done
        export PATH
}

You could use these, e.g.:

appendToPath /home/pi/.rvm/gems/ruby-2.1.1/bin
appendToPath /home/pi/.rvm/gems/ruby-2.1.1@global/bin
appendToPath /home/pi/.rvm/rubies/ruby-2.1.1/bin

-> the three things I see from your post. Prepending to $PATH is most useful if there are system wide version of something you want to override, since paths are checked left to right (for example, if the system has a version of ruby installed as a prereq for something, you can leave that ruby there and prepend the path to your own version). If this isn't the case, appending seems tidier to keep bash from searching ruby/bin first for everything -- however, that's not a hugely significant issue, and prepending may be more foolproof.

You can add those functions and such to ~/.bashrc. For more information about what bash does when initialized, see INVOCATION near the beginning of man bash.

goldilocks
  • 58,859
  • 17
  • 112
  • 227