What would be the appropriate path to use after a shebang in the first line of a ruby source, if I want to use the currently active rvm version of Ruby? I am currently using rvm 1.17.3 I hope it doesn't matter, but just in case I am on Mountain Lion.
on 2012-12-27 05:53
on 2012-12-27 06:29
Its no different with RVM than without. RVM is just a set of scripts that downloads, compiles and installs various rubies for you. It also makes gem sets as well. The gem sets are just symlinked directories. RVM then sets the GEM_HOME, RUBY_HOME, and various shell variables that Ruby normally reads. This means that once you install Ruby via RVM and tell it which one you want to use, it sets the vars and its done. After that its all Ruby itself. So, to answer your question, you would use #!/usr/bin/env as the first line. D. Deryl Downey "The bug which you would fright me with I seek" - William Shakespeare - The Winter's Tale, Act III, Scene II - A court of Justice.
on 2012-12-27 06:43
Correct. My apologies. #!/usr/bin/env ruby -- D. Deryl Downey "The bug which you would fright me with I seek" - William Shakespeare - The Winter's Tale, Act III, Scene II - A court of Justice.
on 2012-12-27 07:23
Thanks, but most shebang files I have seen include an absolute path to the language interpreter. Rvm does not intervene when the shell is interpreting a script containing a shebang. So, for example, if you create this script on OS 10.8 it returns 1.8.7 no matter what version you have selected in rvm. $ cat tryshbang.rb #! /usr/bin/ruby puts RUBY_VERSION $ ./tryshbang.rb 1.8.7 $ I have since found the following recommendation in the Wikipedia article on shebang: http://en.wikipedia.org/wiki/Shebang_(Unix) #! /usr/bin/env ruby puts RUBY_VERSION It works.
on 2012-12-27 07:30
Of course, because you use a FULL path. By not using #!/usr/bin/env ruby (notice the /usr/bin/env part) you're specifically calling a specific ruby which bypasses ALL environment variables and uses the direct binary. No one told you to use #!/usr/bin/ruby. They said #!/usr/bin/env ruby which tells the script to query the path for the first ruby found and use its environment vars, and to make its exit code status be the return value of the script itself, when its done executing. (See man env) -- D. Deryl Downey "The bug which you would fright me with I seek" - William Shakespeare - The Winter's Tale, Act III, Scene II - A court of Justice.
on 2012-12-27 07:37
This is the difference. https://gist.github.com/4386008 -- D. Deryl Downey "The bug which you would fright me with I seek" - William Shakespeare - The Winter's Tale, Act III, Scene II - A court of Justice.
on 2013-01-02 00:32
It's primarily for portability. Using env more or less defeats portability issues as every box could have ruby installed somewhere else. For example rvm really is just a environment hack. When you call a program, in this case ruby, with env your shell will locate the first ruby it finds in the path. This is just a hashed lookup table for speed. Basically when you call for example % ruby program.rb it expands to (say on my system) % /usr/local/bin/ruby /path/to/my/program.rb -- of course rvm takes precedence over the system paths as that's what the utility was designed to do. A common mistake, which your observing, is where a direct path is used; the programmer does not take into account that different operating systems put their binaries in different directories. Always use env. Any of the absolute paths which you see are usually from uninformed dilettantes or users whom want world domination for their tools or OSes and are throwing a fit by forcing any of their users to write a small sed script to patch their install. If you would like to see your paths hash you can simply type in the command hash at the prompt. If you need to update your hash you can use the -r option. If you would like to know more, outside of the web wiki, read the ash (not bash) man page: http://man.freebsd.org/sh Quote: hash [-rv] [command ...] The shell maintains a hash table which remembers the locations of commands. With no arguments whatsoever, the hash command prints out the contents of this table. Entries which have not been looked at since the last cd command are marked with an asterisk; it is possible for these entries to be invalid. With arguments, the hash command removes each specified command from the hash table (unless they are functions) and then locates it. With the -v option, hash prints the locations of the com- mands as it finds them. The -r option causes the hash command to delete all the entries in the hash table except for functions. ~Stu
on 2013-01-02 04:43
Stu wrote in post #1090776: > It's primarily for portability. Using env more or less defeats > portability issues as every box could have ruby installed somewhere > else. > > ... Thanks, Stu, the entire note was very helpful. I am not sure if you are suggesting that I should also be able to have a non-absolute path to env command. Using bash on OS 10.8 I find that a she-bang for Ruby just doesn't work unless it points to some absolute path. The most portable I can make a file is to say #! /usr/bin/env ruby Anyway, that approach meets my needs. Regards, Wes ____ "With consistency a great soul has simply nothing to do. Speak what you think today in hard words and tomorrow speak what tomorrow thinks in hard words again, though it contradict everything you said today. " Ralph Waldo Emerson ____
on 2013-01-02 09:01
Wes ~ That is what I was saying. Also this is correct if you deviate from any posix syntax or use a third party language. So env would also be used for bash or zsh where bashisms( i.e. shell extension) are used but not ash. example to use bash it's the same semantically for portability if one requires bash or zsh specific syntax: #!/usr/bin/env ksh #!/usr/bin/env bash #!/usr/bin/env zsh #!/usr/bin/env fish All bourne derived shells( i.e. not csh) are backward compatible with posix sh which is a small mixture of original bourne syntax and korn syntax. The only time you would ever want to use a direct path is with a posix sh script as so: #!/bin/sh or csh ... but don't use csh =) #!/bin/csh -f If your really curious on the spec you can be read here: http://rubyprogrammer.net/~stu/posix/ You can set your path inside your interactive rc file with the $PATH variable. It's delimited with a colon and is a first positive match wins hash. If your writing a script that depends on knowing where your binaries are you can use a variable to hold the direct path to the executable or set the path variable directly inside the script. Trivial example of embedded ruby embedded inside shell: #!/bin/sh r=/path/to/mri/ruby20 $r <<EOF puts "Hello, world!" RbConfig::CONFIG.each_pair { |k,v| puts k+':<=>:'+v } s=RbConfig::CONFIG.values.grep /bin\/*sh/ puts <<EOR Bye bye your current shell is #{s} Your ruby is ${r} EOR EOF Set the execute bit and run it through a pipe to less or tail -2 for example. Have another ruby. Wanna glue one to the other? Create benchmark results? Just some ideas. Maybe not the most practical examples but provide you some insight on what may be useful with a couple lines of shell code. Bash is an okay shell for beginners. Consider zsh for interactive use as it has a nice flow to development once you begin to customize it. I have ash on FreeBSD which is very fast for shell scripts as it's <70kb binary in contrast to bash being over a meg. I don't believe they ported Almquist's shell to OSX. Maybe homebrew has it (sometimes under the name dash in the gnu distros so I'm unsure what got ported on osx as it's a mashup of FreeBSD kernel with BSD, next and gnu userland)... My main toolset preference tends to be sh for system level automata, primarily because that is my background... consider scripting a network where ruby may or may not be present machine to machine , ruby for larger stack oriented projects where oops, arrays may be needed, zsh, vi, irb for my preferred development stack. I also use rvm which is one of the few bash specific scripts, actually I would call rvm a framework utility at this point, which it is obvious where posix was considered but the need for the automation on directory switching with rvmrc for developers whom needed various sandboxing with minimal setup usurped avoiding the extended syntax of bash. The need for arrays also is where bash becomes the dependency. Take a look at Wayne's code. You will see some of the best shell code by someone who takes such things seriously by studying rvm. Other projects of the same vein such as chruby or rbenv make no effort for portability outside of forcing user to install bash or run a computer only capable of supporting homebrew . I do find it ironic how the author of rbenv promoted it initially with sort of a dunning kruger style marketing his way was the "one true way" when it's far from a minimalist's alternative to rvm while deviating from posix for no reason other than it's obvious the rbenv developer is not a system administrator and knows of nothing other than how to provide FUD with ad hominem bullet points like his lamers statement that rvm is dangerous and error-prone. I guess this sort of thing is how people get themselves noticed when either vying for some corporate employment contract or simply to gain some sort of superficial notoriety. On a simpler level consider command env to work like how you understand how the ruby interpreter yields results from it's block iterators. /usr/bin/env ruby basically has ruby as an argument to the command env which locates ruby in the path hash and yields the result which in this case is the path located to the shell which instructs the kernel to create a memory overlay to load ruby after env evaluates the ruby location; From there ruby will be executed in place in order to evaluate any of the code after which in turn yields each token to the executable. The env will work with any command hashed from the $PATH global environment variable. Happy Hacking. ~Stu
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.