This repository has been archived by the owner. It is now read-only.

npm expects node in PATH #2697

Closed
bastik opened this Issue Feb 4, 2012 · 18 comments

Comments

Projects
None yet
4 participants
@bastik

bastik commented Feb 4, 2012

Hi,

npm should not require node application in PATH. When installing into a local directory, node is in INSTALL_DIR/bin/node. This is fine, I don't need it in PATH. However, npm complains:

~/bin/node/bin$ ./npm --version
/usr/bin/env: node: Permission denied
@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Feb 5, 2012

This is a reasonable expectation. Put INSTALL_DIR/bin in your PATH env, or explicitly call INSTALL_DIR/bin/node INSTALL_DIR/bin/npm <cmd>

isaacs commented Feb 5, 2012

This is a reasonable expectation. Put INSTALL_DIR/bin in your PATH env, or explicitly call INSTALL_DIR/bin/node INSTALL_DIR/bin/npm <cmd>

@isaacs isaacs closed this Feb 5, 2012

@bastik

This comment has been minimized.

Show comment
Hide comment
@bastik

bastik Feb 6, 2012

Maybe reasonable but unnecessary. Why not replace npm by a shell script that finds the node executable and runs $NODE ../lib/npm.js ...?

IMHO, after configure && make && make install the software should run without further setup.

bastik commented Feb 6, 2012

Maybe reasonable but unnecessary. Why not replace npm by a shell script that finds the node executable and runs $NODE ../lib/npm.js ...?

IMHO, after configure && make && make install the software should run without further setup.

@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Feb 6, 2012

IMHO, after configure && make && make install the software should run without further setup.

It does. If we hard coded it to a specific node binary rather than the one in the PATH, it would be a deviation from long-standing traditions. Those traditions are imperfect, but they're expected by most people, and we're not going to realistically change them at this point.

isaacs commented Feb 6, 2012

IMHO, after configure && make && make install the software should run without further setup.

It does. If we hard coded it to a specific node binary rather than the one in the PATH, it would be a deviation from long-standing traditions. Those traditions are imperfect, but they're expected by most people, and we're not going to realistically change them at this point.

@bastik

This comment has been minimized.

Show comment
Hide comment
@bastik

bastik Feb 7, 2012

My idea was something like

#!/bin/sh
NODE_EXEC=`which node || echo ./node`
exec $NODE_EXEC ../lib/npm.js "$@"

bastik commented Feb 7, 2012

My idea was something like

#!/bin/sh
NODE_EXEC=`which node || echo ./node`
exec $NODE_EXEC ../lib/npm.js "$@"
@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Feb 7, 2012

Putting npm behind a sh shim is a bad idea. Just add this to your shell (bashrc or whatever):

alias npm='INSTALL_PATH/bin/node INSTALL_PATH/bin/npm'

isaacs commented Feb 7, 2012

Putting npm behind a sh shim is a bad idea. Just add this to your shell (bashrc or whatever):

alias npm='INSTALL_PATH/bin/node INSTALL_PATH/bin/npm'
@bastik

This comment has been minimized.

Show comment
Hide comment
@bastik

bastik Feb 7, 2012

Why is it a bad idea? E.g. for Java programs, this is standard procedure, because you cannot expect the user to type java -jar /PATH/TO/SOFWARE.jar it order to run the application. Also, it is necessary, if you want to pass arguments to the interpreter (for some reason shebang does not split arguments).

Personally, I know how to cope with this by now. I just want to improve usability for others. Anyway, it's your decision. :-)

bastik commented Feb 7, 2012

Why is it a bad idea? E.g. for Java programs, this is standard procedure, because you cannot expect the user to type java -jar /PATH/TO/SOFWARE.jar it order to run the application. Also, it is necessary, if you want to pass arguments to the interpreter (for some reason shebang does not split arguments).

Personally, I know how to cope with this by now. I just want to improve usability for others. Anyway, it's your decision. :-)

@trentm

This comment has been minimized.

Show comment
Hide comment
@trentm

trentm Mar 6, 2012

I think the worse scenario is not that npm fails saying it can't find node, but that it runs with a different node than you expect. My particular use case was that a call to ./build/node/bin/npm link in my project resulted it in linking into a completely different node that happened to be first on my PATH.

Isaac,
Why not have the shebang line for bin/npm (../lib/node_modules/npm/bin/npm-cli.js) be updated to "#!PREFIX/bin/node" as part of "make install". I.e. in "tools/installer.js". I'll take a stab at a patch.

Why is this a bad idea? What "long-standing traditions" do you mean? Not a tradition in the Perl world (at least on Mac):

$ grep '^#!' /usr/bin/* | grep perl 
...
/usr/bin/mp2bug:#!/usr/bin/perl
/usr/bin/perlbug:#!/usr/bin/perl
/usr/bin/perlbug5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perlbug5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlcc:#!/usr/bin/perl
/usr/bin/perlcc5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perldoc:#!/usr/bin/perl
/usr/bin/perldoc5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perldoc5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlivp:#!/usr/bin/perl
/usr/bin/perlivp5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perlivp5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlthanks:#!/usr/bin/perl
/usr/bin/perlthanks5.8.9:#!/usr/bin/perl5.8.9
...

or in the Python world:

$ grep '^#!' /usr/bin/* | grep python
grep: /usr/bin/ipcs: Permission denied
/usr/bin/2to3:#!/usr/bin/python
/usr/bin/easy_install:#!/usr/bin/python
/usr/bin/idle:#!/usr/bin/python
grep: /usr/bin/sudo: Permission denied
/usr/bin/pydoc:#!/usr/bin/python
/usr/bin/python-config:#!/usr/bin/python
/usr/bin/python2.5-config:#!/System/Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python
/usr/bin/python2.6-config:#!/System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python
/usr/bin/smtpd.py:#!/usr/bin/python
/usr/bin/trial:#!/usr/bin/python2.6
/usr/bin/twistd:#!/usr/bin/python2.6
/usr/bin/xattr:#!/usr/bin/python

or ruby:

$ grep '^#!' /usr/bin/* | grep ruby
grep: /usr/bin/ipcs: Permission denied
/usr/bin/aaf_install:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/cap:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/capify:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/erb:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/ferret-browser:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/gem:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/gen_bridge_metadata:#!/usr/bin/ruby
...

With multiple versions in the wild you have to do this to avoid surprises.

trentm commented Mar 6, 2012

I think the worse scenario is not that npm fails saying it can't find node, but that it runs with a different node than you expect. My particular use case was that a call to ./build/node/bin/npm link in my project resulted it in linking into a completely different node that happened to be first on my PATH.

Isaac,
Why not have the shebang line for bin/npm (../lib/node_modules/npm/bin/npm-cli.js) be updated to "#!PREFIX/bin/node" as part of "make install". I.e. in "tools/installer.js". I'll take a stab at a patch.

Why is this a bad idea? What "long-standing traditions" do you mean? Not a tradition in the Perl world (at least on Mac):

$ grep '^#!' /usr/bin/* | grep perl 
...
/usr/bin/mp2bug:#!/usr/bin/perl
/usr/bin/perlbug:#!/usr/bin/perl
/usr/bin/perlbug5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perlbug5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlcc:#!/usr/bin/perl
/usr/bin/perlcc5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perldoc:#!/usr/bin/perl
/usr/bin/perldoc5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perldoc5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlivp:#!/usr/bin/perl
/usr/bin/perlivp5.10.0:#!/usr/bin/perl5.10.0
/usr/bin/perlivp5.8.9:#!/usr/bin/perl5.8.9
/usr/bin/perlthanks:#!/usr/bin/perl
/usr/bin/perlthanks5.8.9:#!/usr/bin/perl5.8.9
...

or in the Python world:

$ grep '^#!' /usr/bin/* | grep python
grep: /usr/bin/ipcs: Permission denied
/usr/bin/2to3:#!/usr/bin/python
/usr/bin/easy_install:#!/usr/bin/python
/usr/bin/idle:#!/usr/bin/python
grep: /usr/bin/sudo: Permission denied
/usr/bin/pydoc:#!/usr/bin/python
/usr/bin/python-config:#!/usr/bin/python
/usr/bin/python2.5-config:#!/System/Library/Frameworks/Python.framework/Versions/2.5/Resources/Python.app/Contents/MacOS/Python
/usr/bin/python2.6-config:#!/System/Library/Frameworks/Python.framework/Versions/2.6/Resources/Python.app/Contents/MacOS/Python
/usr/bin/smtpd.py:#!/usr/bin/python
/usr/bin/trial:#!/usr/bin/python2.6
/usr/bin/twistd:#!/usr/bin/python2.6
/usr/bin/xattr:#!/usr/bin/python

or ruby:

$ grep '^#!' /usr/bin/* | grep ruby
grep: /usr/bin/ipcs: Permission denied
/usr/bin/aaf_install:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/cap:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/capify:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/erb:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/ferret-browser:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/gem:#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
/usr/bin/gen_bridge_metadata:#!/usr/bin/ruby
...

With multiple versions in the wild you have to do this to avoid surprises.

@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Mar 6, 2012

Why not have the shebang line for bin/npm (../lib/node_modules/npm/bin/npm-cli.js) be updated to "#!PREFIX/bin/node" as part of "make install".

If we do this, then I can't as easily test npm against different versions of node by updating the PATH environment variable.

Update your PATH environment variable so that node is the thing you want it to be, and everything works.

isaacs commented Mar 6, 2012

Why not have the shebang line for bin/npm (../lib/node_modules/npm/bin/npm-cli.js) be updated to "#!PREFIX/bin/node" as part of "make install".

If we do this, then I can't as easily test npm against different versions of node by updating the PATH environment variable.

Update your PATH environment variable so that node is the thing you want it to be, and everything works.

@bastik

This comment has been minimized.

Show comment
Hide comment
@bastik

bastik Mar 6, 2012

If we do this, then I can't as easily test npm against different versions of node by updating the PATH environment variable.

As you suggested yourself, /PATH/TO/DIFFERENT/node ./npm works in this case.

Update your PATH environment variable so that node is the thing you want it to be, and everything works.

It's not about what can be done in theory, when you are already familiar with all the quirks, but about a sane default behaviour and principle of least surprise.

bastik commented Mar 6, 2012

If we do this, then I can't as easily test npm against different versions of node by updating the PATH environment variable.

As you suggested yourself, /PATH/TO/DIFFERENT/node ./npm works in this case.

Update your PATH environment variable so that node is the thing you want it to be, and everything works.

It's not about what can be done in theory, when you are already familiar with all the quirks, but about a sane default behaviour and principle of least surprise.

@trentm

This comment has been minimized.

Show comment
Hide comment
@trentm

trentm Mar 6, 2012

Sure, but then those other tools are the weird ones. I'd say those tools (you mentioned nave elsewhere) need to learn to use "path/to/other/node path/to/your/npm ..." if they want to use 'npm' with an node other than the one with which they are installed.

When you install an "npm" with a node install, it should always work with that specific node. Anything else for deployment means a surprise for users. /usr/bin/env is handy, but is isn't a reliable deployment tool when there are multiple versions and installations of the interpreter in play.

Note that I'm talking about an "npm" that (from the user's p.o.v.) installed with node. If one separately has an npm install (e.g. running from source or whatever), then fine.

trentm commented Mar 6, 2012

Sure, but then those other tools are the weird ones. I'd say those tools (you mentioned nave elsewhere) need to learn to use "path/to/other/node path/to/your/npm ..." if they want to use 'npm' with an node other than the one with which they are installed.

When you install an "npm" with a node install, it should always work with that specific node. Anything else for deployment means a surprise for users. /usr/bin/env is handy, but is isn't a reliable deployment tool when there are multiple versions and installations of the interpreter in play.

Note that I'm talking about an "npm" that (from the user's p.o.v.) installed with node. If one separately has an npm install (e.g. running from source or whatever), then fine.

@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Mar 6, 2012

So, if I understand you correctly, you're suggesting that node's make install should (if installing npm as well) rewrite the first line of $DESTDIR/$PREFIX/bin/npm with #!$PREFIX/bin/node instead of what's there?

isaacs commented Mar 6, 2012

So, if I understand you correctly, you're suggesting that node's make install should (if installing npm as well) rewrite the first line of $DESTDIR/$PREFIX/bin/npm with #!$PREFIX/bin/node instead of what's there?

@trentm

This comment has been minimized.

Show comment
Hide comment
@trentm

trentm Mar 6, 2012

Yes, that's what I'm suggesting.

trentm commented Mar 6, 2012

Yes, that's what I'm suggesting.

@mmalecki

This comment has been minimized.

Show comment
Hide comment
@mmalecki

mmalecki Mar 6, 2012

In my opinion that's a bad idea. People use version managers which change path to node executable but still use global npm. I think that number of people using version managers is greater than number of people installing node outside their PATH.
It also adds unnecessary complexity to installation process.

mmalecki commented Mar 6, 2012

In my opinion that's a bad idea. People use version managers which change path to node executable but still use global npm. I think that number of people using version managers is greater than number of people installing node outside their PATH.
It also adds unnecessary complexity to installation process.

@trentm

This comment has been minimized.

Show comment
Hide comment
@trentm

trentm Mar 6, 2012

Possible patch (against v0.6 branch for now) for this: https://gist.github.com/1989462

Interested in a pull request?

trentm commented Mar 6, 2012

Possible patch (against v0.6 branch for now) for this: https://gist.github.com/1989462

Interested in a pull request?

@trentm

This comment has been minimized.

Show comment
Hide comment
@trentm

trentm Mar 6, 2012

@mmalecki Neither of us has data on that. I suspect that eventually there will be more people just installing node with the nodejs.org-provided installers which installs a npm with their node install vs. people that install npm separately.

However, I think that is beside the point. When node core decided to include npm with node around v0.6.3, that was a decision that "this npm belongs to this node". An npm installed with that node should use that node by default. A comparatively native user shouldn't have to get the surprise of "/usr/local/bin/npm link foo" or "/usr/local/bin/npm install -g foo" linking to or install into a node other than the one at /usr/local.

It is the person using a version manager who is the most reasonable position to know that they are using that /usr/local/bin/npm atypically. The burden should be on them to have aliases or wrappers or whatever for convenience of using that npm with a node to which it doesn't belong.

trentm commented Mar 6, 2012

@mmalecki Neither of us has data on that. I suspect that eventually there will be more people just installing node with the nodejs.org-provided installers which installs a npm with their node install vs. people that install npm separately.

However, I think that is beside the point. When node core decided to include npm with node around v0.6.3, that was a decision that "this npm belongs to this node". An npm installed with that node should use that node by default. A comparatively native user shouldn't have to get the surprise of "/usr/local/bin/npm link foo" or "/usr/local/bin/npm install -g foo" linking to or install into a node other than the one at /usr/local.

It is the person using a version manager who is the most reasonable position to know that they are using that /usr/local/bin/npm atypically. The burden should be on them to have aliases or wrappers or whatever for convenience of using that npm with a node to which it doesn't belong.

@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Mar 6, 2012

@trentm It looks like that patch is against master. (Which is fine, that's where this should go anyway.)

isaacs commented Mar 6, 2012

@trentm It looks like that patch is against master. (Which is fine, that's where this should go anyway.)

@isaacs

This comment has been minimized.

Show comment
Hide comment
@isaacs

isaacs Mar 6, 2012

Oops, premature send. Yes, pull req, please.

isaacs commented Mar 6, 2012

Oops, premature send. Yes, pull req, please.

trentm added a commit to trentm/node-1 that referenced this issue Mar 7, 2012

@trentm

This comment has been minimized.

Show comment
Hide comment

trentm commented Mar 7, 2012

pull req: #2886

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.