在Ubuntu中使用Node Package Manager无法安装软件包

525
在Ubuntu上,NodeJS解释器的名称(node)已被改为nodejs,因为与另一个软件包存在名称冲突。以下是Debian的自述文件所说的内容:

Node.js解释器命令的上游名称是“node”。 在Debian中,解释器命令已更改为“nodejs”。

这样做是为了防止命名空间冲突:其他命令在其上游中使用相同的名称, 如来自“node”软件包的ax25-node。

调用Node.js作为shell命令的脚本必须更改为使用“nodejs”命令。

然而,使用nodejs安装使用npm的软件包会出现问题。 安装软件包时会失败并显示以下错误:

sh: 1: node: not found
npm WARN This failure might be due to the use of legacy binary "node"
npm WARN For further explanations, please read /usr/share/doc/nodejs/README.Debian
我该如何让npm知道系统中已经安装了nodejs,但解释器的名称不同?

29
你可以尝试在/usr/bin中运行ln -s nodejs node,但这有点像是一种黑客行为。 - vbo
1
@vbo,你可以将其添加为答案 - 它解决了问题! - Himel Nag Rana
2
@HimelNagRana 我有另一个(更好,被接受的)答案。我的初始评论也被转化为答案(https://dev59.com/7WEi5IYBdhLWcg3wjs1j#21168305)。 - vbo
4
使用 NVM 安装和管理 Node.js 版本,https://github.com/creationix/nvm,它简单方便! - Unitech
2
我强烈推荐使用此解决方案:https://dev59.com/7WEi5IYBdhLWcg3wjs1j#38325376,以便随时控制节点和npm版本,并用于任何用途。 - Rémi Becheras
19个回答

1111

简而言之:

sudo apt-get install nodejs-legacy

首先让我澄清一下情况。在2012年夏天,Debian的维护者决定将Node.js可执行文件更名,以避免与另一个软件包发生某种名称空间冲突。这是Debian技术委员会做出的非常艰难的决定,因为它破坏了向后兼容性。

以下是委员会决议草案的引用,发布在Debian邮件列表中:

  1. nodejs软件包应更改为提供/usr/bin/nodejs而不是/usr/bin/node。该软件包应声明与在Debian中引用/usr/bin/node的任何软件包存在Breaks:关系。

  2. nodejs源代码软件包还应提供一个nodejs-legacy二进制软件包,其优先级为extra,并将/usr/bin/node作为指向/usr/bin/nodejs的符号链接。存档中的任何软件包都不得依赖于或推荐nodejs-legacy软件包,该软件包仅用于上游兼容性。此软件包也应声明与node软件包存在冲突关系。

<...>

第2段是OP问题的实际解决方案。OP应该尝试安装这个软件包,而不是手动创建符号链接。这是Debian软件包索引网站中此包的链接。

可以使用sudo apt-get install nodejs-legacy进行安装。

我没有找到有关NPM开发人员采用整个事物的任何信息,但我认为npm软件包最终会得到修复,而nodejs-legacy将真正成为遗留版。


107
总结一下:sudo apt-get install nodejs-legacy - Alf Eaton
60
我喜欢详细解释情况的答案,而不仅是盲目执行指令。这样我可以将这些信息复制到我的环境设置脚本的注释中,以便在一年后当它无法正常工作时我仍然知道发生了什么。 - Mnebuerquo
29
作为一个人,我认为节点不是节点,而是Debian上的nodejs,这非常不方便。将开发工具分裂成这样实在是非常愚蠢。基本上,这个决定在每个Node.js包中为Debian创造了一个特殊的情况!我从未听说过“节点”有其他用途,所以我没有任何同情心 ;( - Lodewijk
4
除非我漏掉了什么,否则这不是一个命名空间冲突。这里没有命名空间,这只是一个简单的名称冲突。命名空间允许您同时拥有相同的名称(两次或多次),只要每个名称存在于不同的命名空间中。在Linux或Unix中,没有这样的“空间”可用于可执行文件名称。最接近的是您可以在$ PATH变量中有多个目录,并且使用具有匹配命名的可执行文件的最早目录。(但这实际上与命名空间非常不同。) - iconoclast
7
这非常令人烦恼,尤其是因为名称冲突涉及到一个名为“Amateur Packet Radio”的东西。 - Suzana
显示剩余8条评论

114

尝试将node链接到nodejs。首先找出nodejs的位置。

whereis nodejs

然后将软链接节点链接到Node.js

ln -s [the path of nodejs] /usr/bin/node 

我假设 /usr/bin 已经在你的执行路径中。然后你可以通过在命令行中输入 node 或 npm 来进行测试,现在应该一切正常了。


3
-s 创建符号链接(通常是首选),而不是硬链接。 - hyde
20
这个方法可行,但是vbo的回答安装nodejs-legacy包更加简单。 - Don Kirkby
2
我赞同Don Kirkby和vbo的评论和答案。我认为vbo的答案应该被选为最佳答案。 - modulitos
3
我发现创建符号链接比安装同样的软件两次更加方便。 - weisk
7
除非你是dpkg,否则不要对/usr/bin进行操作。如果你喜欢手动符号链接的方法,正确的做法是在/usr/local/bin中创建符号链接,该目录专为本地安装和覆盖而设。在/usr/bin手动进行的任何操作都可能被包管理器覆盖或混淆。 - tripleee
显示剩余4条评论

46
您还可以使用NVM Nodejs版本管理器 来安装Nodejs。使用版本管理器有很多优点,其中之一是您不必担心这个问题。

说明:

sudo apt-get update
sudo apt-get install build-essential libssl-dev

安装必要的软件包后,您可以从该项目的 GitHub 页面下载 nvm 安装脚本。版本号可能会有所不同,但通常情况下,您可以使用以下语法下载并安装:

curl https://raw.githubusercontent.com/creationix/nvm/v0.16.1/install.sh | sh

这将下载脚本并运行它。它会将软件安装到家目录的子目录~/.nvm中。它还会向您的~/.profile文件添加必要的行以使用该文件。

为了访问nvm功能,您需要注销并重新登录,或者可以源化~/.profile文件,以使当前会话知道这些更改:

source ~/.profile

现在你已经安装了nvm,你可以安装独立的Node.js版本。

要找出可供安装的Node.js版本,您可以输入以下命令:

nvm ls-remote
. . .

v0.11.10
v0.11.11
v0.11.12
v0.11.13
v0.11.14

正如您所看到的,在本文撰写时最新版本为v0.11.14。您可以通过输入以下命令来安装:

nvm install 0.11.14

通常,nvm会切换到使用最近安装的版本。您可以通过输入以下内容明确告诉nvm使用我们刚下载的版本:

通常情况下,nvm将切换到使用最近安装的版本。您可以通过输入以下命令来显式地告诉nvm使用我们刚刚下载的版本:

通常情况下,nvm会自动切换到最近安装的版本。您也可以通过输入以下命令明确指定使用刚下载的版本:

通常,nvm会切换到使用最近安装的版本。您可以通过输入以下命令明确告诉nvm使用我们刚刚下载的版本:

nvm use 0.11.14

当您使用nvm安装Node.js时,可执行文件称为node。您可以通过键入以下内容在Shell中查看当前使用的版本:

node -v

node -v

完整的教程可以在这里找到。


3
这也为我解决了上面的错误。对于 Node.js 开发人员来说更好(在我看来是所有开发人员,尽管我不是从事 Node.js 工作的人)。我已经使用它了。 - Ajeeb.K.P
1
我需要将nvm节点软链接到usr/bin/node。因此运行了sudo ln -s /home/www/.nvm/v0.10.36/bin/node /usr/bin/node - Jason Kim
2
我已经花了几个小时来尝试解决这个问题...这是我找到的唯一可行的解决方案。谢谢。 - w3bMak3r
"benefits"现在是一个无效链接。 - jaunt

20
  1. 首先使用以下命令安装nvm

    curl https://raw.githubusercontent.com/creationix/nvm/v0.11.1/install.sh | bash
    
    运行命令
    source ~/.profile
    
    现在运行此命令,它将显示所有已安装或其他版本的软件包:
  2. nvm ls-remote
    
  3. 已安装的软件包会显示为绿色。安装您想要的任何版本:

  4. nvm install 6.0.0
    
  5. 检查“where”未安装的位置:

    which node
    
  6. 检查当前版本:

  7. node -v
    
    n=$(which node);
    n=${n%/bin/node}; 
    chmod -R 755 $n/bin/*; 
    sudo cp -r $n/{bin,lib,share} /usr/local
    

2
我强烈推荐这个解决方案,可以随时控制节点和npm版本,适用于任何情况。 - Rémi Becheras

14
sudo apt-get --purge remove node
sudo apt-get --purge remove nodejs-legacy
sudo apt-get --purge remove nodejs

sudo apt-get install nodejs-legacy
source ~/.profile

将被折叠的评论中的source ~/.profile与已接受答案相结合,并添加一些清理命令。 很可能您还需要在之后执行sudo apt-get install npm


12

对我来说,问题得到了解决,方法是:

sudo apt-get remove node
sudo apt-get remove nodejs
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo ln -s /usr/bin/nodejs /usr/bin/node
alias node=nodejs
rm -r /usr/local/lib/python2.7/dist-packages/localstack/node_modules
npm install -g npm@latest || sudo npm install -g npm@latest

10

这是我使用的另一种方法,因为我喜欢n可以轻松切换Node版本。

在新的Ubuntu系统上,首先安装"system" Node:

curl -sL https://deb.nodesource.com/setup | sudo bash -

然后全局安装n模块:

npm install -g n

由于系统节点首先安装(如上所述),因此可以使用替代系统来干净地指向n提供的节点。首先确保替代系统没有节点:

update-alternatives --remove-all node

然后添加n提供的节点:

update-alternatives --install /usr/bin/node node /usr/local/bin/node 1

接下来添加系统提供的节点(使用curl安装的节点):

update-alternatives --install /usr/bin/node node /usr/bin/nodejs 2

现在使用交互菜单选择由n提供的节点(从以下命令呈现的菜单中选择/usr/local/bin/node):

update-alternatives --config node

最后,由于 /usr/local/bin 通常在 PATH 中的优先级高于 /usr/bin,如果要使用 alternatives 系统的 node,则必须创建以下别名(输入到您的 .bashrc 或 .zshrc 文件中),否则安装在 /usr/local/bin 中的 node 将始终具有优先权:

alias node='/usr/bin/node'

现在你可以使用 n <desired node version number> 轻松地在不同的 Node.js 版本之间切换。


9
在Linux Mint 17上,我尝试了创建符号链接或使用“nodejs-legacy”包的两种解决方案,但都没有成功。
最终对我有用的是使用Chris Lea的ppa。
sudo apt-get purge node-*
sudo apt-get autoremove 
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs

这个安装了Node版本为10.37和npm版本为1.4.28。之后,我可以全局安装包。


9

正如其他人已经提到的,我建议不要使用“sudo apt-get”安装node或任何开发库。您可以从https://nodejs.org/dist/v6.9.2/下载所需版本并设置自己的环境。

我推荐使用像nvmn这样的工具来管理您的node版本。使用这些模块非常方便,可以轻松切换版本。 https://github.com/creationix/nvm https://github.com/tj/n

或者编写基本的bash脚本来下载zip/tar文件,解压并移动文件夹并创建软链接。每当需要更新时,只需将旧的软链接指向新下载的版本即可。 就像我为自己创建的那样,您可以参考: https://github.com/deepakshrma/NodeJs-4.0-Reference-Guide/blob/master/nodejs-installer.sh

#Go to home
cd ~
#run command
#New Script
wget https://raw.githubusercontent.com/deepakshrma/NodeJs-4.0-Reference-Guide/master/nodejs-installer.sh 
bash nodejs-installer.sh -v lts
#here -v or --version can be sepecific to 0.10.37 or it could be latest/lts 
#Examples
bash nodejs-installer.sh -v lts
bash nodejs-installer.sh -v latest
bash nodejs-installer.sh -v 4.4.2

7

这里提供了一种简单的解决方案,可以从此处获取。

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash --
sudo apt-get install nodejs

你可以通过更改setup_x.x的值来指定版本,例如将其更改为setup_5.x。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接