learinMN
learinMN

Reputation: 23

-bash: /usr/local/bin/rbenv: /usr/bin/env: bad interpreter: Permission denied shows up everytime I try to use npm

Everytime I try to use npm I get the error above. Python works fine on my computer but npm and node never work.

Upvotes: 1

Views: 7416

Answers (1)

mklement0
mklement0

Reputation: 439607

The error message you're getting suggests that executable script /usr/local/bin/rbenv has a shebang line specifying executable /usr/bin/env (#!/usr/bin/env ...).

The fact that it says Permission denied means that, for some reason, /usr/bin/env is not executable, or at least not executable by you.

This is highly unusual, because /usr/bin/env is a frequently used standard utility. I would start investigating there, such as by running ls -l /usr/bin/env to see the permissions.

More broadly, the question is why rbenv - a utility for managing multiple Ruby environments - is involved here at all.

I suggest deactivating it at least temporarily while troubleshooting - comment out the line that loads rbenv in your shell's profile/initialization file (in Bash: ~/.bash_profile or ~/.bashrc - see https://github.com/sstephenson/rbenv#how-rbenv-hooks-into-your-shell), then open a new terminal window.

Finally, some background info on how npm is normally launched on a Unix system:

  • npm is a symlink located in your $PATH that points to an executable script named npm-cli.js.
  • npm-cli.js, despite containing JavaScript, actually uses #!/bin/sh as its shebang line, which means that the shell (sh) initially executes the file.
  • The 2nd line in npm-cli.js is in fact the only line that sh executes:
    • // 2>/dev/null; exec "`dirname "$0"`/node" "$0" "$@"
    • The line starts with // so that node later ignores it (since, in JavaScript, it is a comment), given that the line's sole purpose is to invoke node.
    • From the shell's perspective, // is an attempt to run // as a command, which invariably fails, so 2>/dev/null is appended to suppress the error message.
    • exec "`dirname "$0"`/node" "$0" "$@" then effectively relays invocation of the script at hand to the node executable:
      • exec replaces the running sh instance with the command specified.
      • "`dirname "$0"`/node"` specifies the node executable as residing in the same directory as the the npm symlink (which makes sense, given that both node and npm are always installed in the same directory).
      • $0 refers to the script itself (the npm symlink)
      • "$@" simply passes all arguments passed to npm through.
  • My guess is that the reason for this indirect invocation is to ensure that the node executable that is used to execute the npm script is from the same Node.js version. If a simple #!/usr/bin/env node shebang were used, then whatever node executable comes first in the $PATH would be used.

Upvotes: 5

Related Questions