This project is archived and is in readonly mode.

#4885 ✓resolved
Scott Taylor

[PATCH] bin/rails missing shebang line

Reported by Scott Taylor | June 17th, 2010 @ 03:15 AM

bin/rails was missing the shebang line. Here's a patch:

http://github.com/smtlaissezfaire/rails/tree/bin_executable

Comments and changes to this ticket

  • Rohit Arondekar

    Rohit Arondekar June 17th, 2010 @ 03:45 PM

    AFAIK it will allow you to execute rails directly. Rubygem uses Kernel#load to pull in binfiles into a bin wrapper. Can you give a good use case for adding the shebang line?

  • Santiago Pastorino

    Santiago Pastorino June 17th, 2010 @ 04:23 PM

    • State changed from “new” to “invalid”

    Despite it's good to have the shebang line for executable files, this line is automatically generated by rubygems.

  • cldwalker

    cldwalker June 18th, 2010 @ 04:44 AM

    Having a shebang in an executable does matter. Not everyone uses rubygems to manager their gems. You should take a look at the ruby packaging standard, the emerging standard for packaging ruby libraries. It clearly states: "Ruby executables SHOULD have a shebang line using env: #!/usr/bin/env ruby"

    Here's what happens when I try use rails with rip:

    $ rails
    /Users/bozo/.rip/active/bin/rails: line 1: syntax error near unexpected token `('
    /Users/bozo/.rip/active/bin/rails: line 1: `$:.unshift File.expand_path("../../lib", __FILE__)'
    

    This happens because rip expects the rails executable to be a fully functional executable and have a shebang line. In not having a shebang, rails is choosing to be different than the majority of libraries out there, going against the emerging standard and forcing us to use rubygems. Is there a reason why rails should force us to use rubygems?

  • Rohit Arondekar

    Rohit Arondekar June 18th, 2010 @ 05:41 AM

    • State changed from “invalid” to “open”
    • Assigned user set to “José Valim”

    cldwalker, thank you for that. I honestly didn't know that's why I asked Scott to explain why it was needed. I've opened the ticket.

    Although Scott I think you'll need to make a patch, see the contributor guide http://rails.lighthouseapp.com/projects/8994/sending-patches

  • Scott Taylor

    Scott Taylor June 18th, 2010 @ 05:59 AM

    Yeah - I ran into in a context outside of rubygems (running the executable directly).

    Attached is the patch.

  • Santiago Pastorino

    Santiago Pastorino June 18th, 2010 @ 11:58 AM

    I'm not against having the shebang, all the executable files on unix should have it. Ruby executables should have #!/usr/bin/env ruby
    I've answered quickly because i had requested this some time ago, when rip just come out, and my request was denied.
    But i agree so sorry for closing it :).

  • raggi

    raggi June 18th, 2010 @ 02:04 PM

    No, there's no reason rails should "force" you to use rubygems, however, the RPS has not yet provided one key aspect of information that is being completely ignored here:

    The RPS also says:

    Executables SHOULD NOT require 'rubygems' or modify the $LOAD_PATH.
    

    So, my question to you is, if whatever packaging system you're using as an alternative does not generate bin wrappers with correct shebang lines that then use "exec" or "load" (exec would require modifying $RUBYLIB or similar), then you're going to have to violate the above to make this really work. I will describe why this is a problem after some further notes.

    The only other way to make it work "by hand", is to launch the binary like this:

    ruby -Irails/lib bin/rails
    

    However this is also insufficient without the packaging system further modifying the load path prior to loading the application, as other dependencies are required to be on the load path, as is clearly demonstrated if you do in fact do this:

    Thor is not available.
    If you ran this command from a git checkout of Rails, please make sure thor is installed,
    and run this command as `ruby /path/to/rails myapp --dev`
    

    Please think about specifications that you're trying to use to force in patches, and if you're going to adhere to one portion of the spec, you should adhere to the rest, as such the patch technically should also be removing the following code from bin/rails:

    rescue LoadError
      railties_path = File.expand_path('../../railties/lib', __FILE__)
      $:.unshift(railties_path)
      require "rails/cli"
    end
    

    I don't think that any of this is a good idea, I think that the original authors have actually made a very sane choice in how the software is currently loading its code. My largest problem with these kinds of suggestions is that they're based on an incomplete specification (that is still marked draft for good reason, and the standard has had my own input, I am not some random just making noise for no reason), and with an incomplete knowledge of good packaging procedures and load path management.

    I would strongly suggest that better guidelines for making this work actually involve writing correct load path modification prior to launching the binfile in order to avoid the requirement for load path modifications within binfiles by library authors.

    The reasoning behind this is:

    Different packaging systems disagree on what to put in the load path. Some will use relative paths, and others will use absolute paths. There is no "right way", and in the spirit of ruby, the specification does not try to force either on the user, instead, it suggests a process by which users will not generate errors. The ignoring of this portion of the specification causes double load errors under conditions where the library is authored for one packaging system that believes in one mode of load path management, and then used by a different packaging system that has a conflicting view about whether or not the load path should contain absolute or relative paths. It is for this issue that chris included the aforementioned terms in the RPS, and this should be accounted for prior to further discussion on the topic.

    It is also worth noting that rails supports the windows platform where the shebang is completely irrelevant, and the RPS currently makes no attempts to support this platform (yet), as it is still in draft and requires further input from Windows rubyists. Regardless of your personal opinions/beliefs about this platform, the languages continued support is important to users and again, should be accounted for in further discussion on the topic.

  • Rohit Arondekar

    Rohit Arondekar June 18th, 2010 @ 02:55 PM

    • Assigned user changed from “José Valim” to “Rohit Arondekar”

    Thank you for the thorough explanation James (raggi). Can somebody still provide a good argument for putting in only the shebang line? Or maybe making a more comprehensive patch? If not I'll have to close this ticket.

    P.S Thank you everyone for the discussion, has been very insightful & educational. :)

  • Scott Taylor

    Scott Taylor June 18th, 2010 @ 04:00 PM

    So, my question to you is, if whatever packaging system you're using as an alternative does not generate bin wrappers with correct shebang lines that then use "exec" or "load" (exec would require modifying $RUBYLIB or similar), then you're going to have to violate the above to make this really work. I will

    I'm not exactly sure what require "rubygems" and $LOAD_PATH have to do with the she-bang line. As far as I'm concerned, the shebang line is a unix way to know which bin to use when running ./myexecutable. It's language agnostic.

    Notice that my original usage was outside of a package management system. I think the way we should be writing code is by asking ourselves, "What can we make agnostic to all package managers, such that we aren't writing for any one given package manager, or a package manager at all".

    Just because the shebang is being adopted, it doesn't mean that require "rubygems" and $LOAD_PATH must be as well.

    It is also worth noting that rails supports the windows platform where the shebang is completely irrelevant, and the RPS currently makes no attempts to support this platform (yet), as it is still in draft and requires further input from Windows rubyists. Regardless of your personal opinions/beliefs about this platform, the languages continued support is important to users and again, should be accounted for in further discussion on the topic.

    This is the only argument that seems to make sense to me. Windows doesn't seem to have an equivalent of the shebang, and neither does any other platform, AFAIK.

  • raggi

    raggi June 18th, 2010 @ 04:19 PM

    Without a correct load path, a shebang is completely useless. Add the shebang, and then run bin/rails:

    % bin/rails
    Thor is not available.
    If you ran this command from a git checkout of Rails, please make sure thor is installed,
    and run this command as `ruby /path/to/rails myapp --dev`
    

    My point is simple. Packaging is required to setup the load path correctly in a way that satisfies out of repository dependencies. Packaging should not be modifying the load path implicitly. A packaging standard which is yet to be written at all would state this more clearly, the reasoning is similar to issues already described.

    I don't necessarily have a problem with adding a shebang line, just as I don't have a problem with the modification of load path that bin/rails choses to do (specifically conditionally), as I think it maybe could make sense for rails, but, I don't think that using the RPS as a reason is valid at all.

    My question is, in the environment you're proposing to use, will adding a shebang line actually make the binary work? If so, how is the load path being managed / how is the code being split in order to make this work?

  • raggi

    raggi June 18th, 2010 @ 04:22 PM

    In other words, can you provide a reason for adding it beyond "all unix binfiles have one"?

    It is worth noting that whilst becoming increasingly rare, not all platforms with unix like shbang semantics have env(1) in /usr/bin/env.

  • raggi

    raggi June 18th, 2010 @ 04:28 PM

    It is also worth considering these:

    http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/envir...
    http://www.in-ulm.de/~mascheck/various/shebang/

    This particularly becomes a problem on shared systems when using for example AWS keys in env vars or the like, and can lead to complete disclosure to other smart enough users.

  • cldwalker

    cldwalker June 18th, 2010 @ 07:09 PM

    • Assigned user changed from “Rohit Arondekar” to “josh”

    In other words, can you provide a reason for adding it beyond "all unix binfiles have one"?

    I don't understand how you missed my rip example but I'll restate it. As the rails executable exists now, it's broken and unusable outside of rubygems. I gave an example with rip but the same applies with other gem managers i.e. rpg and coral. AFAIK, most gem managers don't rewrite executables as rubygems does.

    My question is, in the environment you're proposing to use, will adding a shebang line actually make the binary work? If so, how is the load path being managed / how is the code being split in order to make this work?

    Yes, it will make it work. It works for all other executables except Rails. How it works along with other issues you've raised (why this patch doesn't address $LOAD_PATH and how RPS doesn't handle windows) are all digressions.

    In adding this two line patch, rails become gem manager agnostic. This shouldn't negatively effect anyone who is successfully using the rails executable in its current form. I have yet to see a relevant objection.

  • raggi

    raggi June 18th, 2010 @ 07:46 PM

    Agreed they are digressions.

    I have not objected to adding a shebang, I have objected to the reason being "because RPS says so", because as stated, consistent application of RPS would break other modes of use.

    As far as the security implications go, they are worth noting, that is all.

    As I said to Rohit, I don't think I should comment on rails tickets.

  • raggi

    raggi June 18th, 2010 @ 08:04 PM

    What I mean is, when I asked

    My question is, in the environment you're proposing to use, will adding a shebang line actually make the binary work?"

    If you said "yes", then my answer is +1. As indicated by:

    I don't necessarily have a problem with adding a shebang line, just as I don't have a problem with the modification of load path that bin/rails choses to do (specifically conditionally), as I think it maybe could make sense for rails, but, I don't think that using the RPS as a reason is valid at all."

    God I don't get how these things get so pathetic so damned fast.

    Anyway, I'm waiting on an install to see if the answer is indeed yes, assuming it is, ofc, my answer is +1.

  • Repository

    Repository June 19th, 2010 @ 08:55 AM

    • State changed from “open” to “resolved”

    (from [4bfff05f37b8416496d25a045c0e1c38368f1e31]) add missing shebang to rails bin. LH [#4885 state:resolved]

    Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
    http://github.com/rails/rails/commit/4bfff05f37b8416496d25a045c0e1c...

  • Ryan Bigg

    Ryan Bigg October 9th, 2010 @ 09:46 PM

    Automatic cleanup of spam.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Attachments

Referenced by

Pages