I installed Ubuntu using WSL2 on Windows 11 and configured oh-my-zsh as my default shell. After that, I created /etc/wsl.conf and added the following lines:
[interop]
appendWindowsPath=false
to not include the Windows PATH in WSL. Now, my zsh shell can't pick any installation like node, npm or vscode. It must be because of some config edit I need to make in ~/.zshrc configuration file. What am I supposed to do here?
Add these few lines in the .zshrc file:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_comp$
I've installed node version 12 using the below commands.
$ nvm install 12 -g
# note - nvm use 12.13.1 has same effect
v12.13.1 is already installed.
Now using node v12.13.1 (npm v6.12.1)
When I type $ node -v to confirm the node version, the command line reads v12.13.1.
I have also set it as my default node version.
$ nvm alias default 12.13.1
default -> 12.13.1 (-> v12.13.1)
Yet when I open a new window I still see version 10.
$ node -v
v10.17.0
and I have to
$ nvm use 12
every time I open a new window
and then I have
$ node -v
v12.13.1
How can I have 12 be my default without doing use every time ?
This is on Ubuntu, my .bashrc includes:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
I removed npm by removing the ~/.npm folder and then reinstalled npm with:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash
and version 12 of node with
nvm install 12
node -v
This fixed it and now new terminal windows now show
node -v
v12.13.1
I downloaded NVM (on Mac High Sierra), with:
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
download works, but then there's an error:
Appending nvm source string to /Users/User/.bashrc
bash: line 353: /Users/User/.bashrc: Permission denied
=> Appending bash_completion source string to /Users/User/.bashrc
bash: line 360: /Users/User/.bashrc: Permission denied
How can I grant it permission - or manually add the strings to .bashrc? And if so what does the string need to be?
The lines you are looking for are the following:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Append them at final of you .bashrc.
Here are my steps in my
steps:
-run:
name: Setup nvm and npm
command: |
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
export NVM_DIR=$HOME/.nvm
source $NVM_DIR/nvm.sh
nvm install 8.9 && nvm alias default 8.9
-run: npm install && npm run lint && npm test
The second step always fails with this error message
/bin/bash: npm: command not found
I checked .bashrc and I can see the following lines are added to the end of the file
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Circleci 2.0 invokes the step command by starting a new shell with #!/bin/bash -eo pipefail
If I starts a docker (docker run -i -t buildpack-deps:xenial) and apply the first step, and then start a new shell via #!/bin/bash -eo pipefail, I can see npm is available on the path
I am using docker for this project
version: 2
jobs:
test_main:
docker:
- image: buildpack-deps:xenial
So why does it fail in circleci 2.0 environment? How can I ensure npm will be available to step 2 from step 1?
I have tried to add [ -s "$HOME/.bashrc" ] && \. "$HOME/.bashrc" to ~/.bash_profile (in case .bashrc is not executed due to the non-interactive/non-login shell)
To reproduce the issue you can run circleci build with this .circleci/config.yml file
version: 2
jobs:
build:
docker:
- image: buildpack-deps:xenial
steps:
- run:
name: Setup nvm and npm
command: |
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
# Activate nvm
export NVM_DIR=$HOME/.nvm
touch $HOME/.nvmrc
source $NVM_DIR/nvm.sh
# Use node 8.9
nvm install 8.9 && nvm alias default 8.9
echo 8.9 > $HOME/.nvmrc
# Enable nvm in following steps
echo '[ -s "$HOME/.bashrc" ] && \. "$HOME/.bashrc"' >> $HOME/.bash_profile
# To fix npm install : "node-pre-gyp: Permission denied"
npm config set user 0
npm config set unsafe-perm true
npm install -g npx webpack webpack-cli jest
node --version
npm --version
- run: npm install
You will see the following error message:
====>> npm install
#!/bin/bash -eo pipefail
npm install
/bin/bash: npm: command not found
Error: Exited with code 127
Step failed
Task failed
The problem lies with these lines:
# Enable nvm in following steps
echo '[ -s "$HOME/.bashrc" ] && \. "$HOME/.bashrc"' >> $HOME/.bash_profile
I was hoping to source .bashrc from .bash_profile. However since the shell of circleci is non-interactive, the environment variable PS1 is blank. Hence .bashrc basically quits immediately once it is sourced, because of this line in .bashrc
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
I have to put the following lines directly in the file specified by $BASH_ENV
echo 'export NVM_DIR=$HOME/.nvm' >> $BASH_ENV
echo 'source $NVM_DIR/nvm.sh' >> $BASH_ENV
I found that changing default node by nvm is not working for my steps.
Solved by:
- run:
name: 'Install Project Node'
command: |
set +x
source ~/.bashrc
nvm install 12
NODE_DIR=$(dirname $(which node))
echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV
Just source /opt/circleci/.nvm/nvm.sh in the beginning of every step.
In the system there is a nodejs, installed through nvm. The command is not running npm.
Console is Oh my zsh
You can use zsh-nvm or enable it yourself by adding following lines to your ~/.zshrc
export NVM_DIR=~/.nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
Extra:
For faster shell initialization, I use lazynvm which only loads node when needed
lazynvm() {
unset -f nvm node npm
export NVM_DIR=~/.nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
}
nvm() {
lazynvm
nvm $#
}
node() {
lazynvm
node $#
}
npm() {
lazynvm
npm $#
}
Reference: Lazy load nvm for faster shell start
Switching from Bash to Oh-My-Zsh
If you already have nvm installed and you're switching from bash to oh-my-zsh you can simply open up your .zshrc file and add the nvm plugin that is included with oh-my-zsh:
Open your zsh config file.zshrc in nano with this command: nano ~/.zshrc
Scroll down to where it shows plugins=(git) and add nvm inside the parentheses to make it show as plugins=(git nvm) (separate plugins with spaces)
Press control + O (on macOS), then enter, to save, then press control + X to exit
Then open a new terminal window/tab and enter nvm ls to confirm it works. Note that you must open a new window/tab for your shell to use the newly updated .zshrc config (or enter source ~/.zshrc, etc.)
Source: https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/nvm
This worked for me on Ubuntu 20.04.
Install or update nvm
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
Add in your ~/.zshrc
echo 'export NVM_DIR=~/.nvm' >> ~/.zshrc
echo '[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' >> ~/.zshrc
Load in the current shell environment
source ~/.zshrc
Check the nvm version
nvm -v
use homebrew to install nvm
brew install nvm
edit your system configuration
vim ~/.zshrc # or vim ~/.bashrc
export NVM_DIR=~/.nvm
esc > :wq
save file
reload the configuration
source $(brew --prefix nvm)/nvm.sh
view nvm version
$ nvm --version
# 0.36.0
enjoy it.
A much easier solution is to use the nvm plugin that is shipped by default:
It also automatically sources nvm, so you don't need to do it manually
in your .zshrc
git clone https://github.com/nvm-sh/nvm.git ~/.nvm
cd ~/.nvm && git checkout v0.35.1 (current latest release)
Add nvm to your ~/.zshrc. Ex: plugins=(... nvm)
I discovered that there is a nvm plug-in shipping with oh-my-zsh (that's different from lukechilds plugin). After short inspection, I think it adds the necessary modifications to .zshrc when loading, so simply adding nvm to the plugins list in .zshrc should work as well (and it does for me).
I did not find any more details on that default nvm plugin via google so I don't know whether this is the "go-to" solution.
Add this code to .zshrc on your user directory
export NVM_DIR="$HOME/.nvm"
[ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh" # This loads nvm
[ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm" # This loads nvm bash_completion
Then run this code on your terminal:
source ~/.zshrc
With Linux (Ubuntu 20.04, 22.04 and 22.10)
With your favorite editor, you edit ~/.zshrc
nano or vi ~/.zshrc
At the end of the file, you add :
# NVM
export NVM_DIR=~/.nvm
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
And then you run :
source ~/.zshrc
I strongly suggest using christophemarois' approach to lazy loading nvm (node, npm and global packages) in order to avoid slow shell starting times:
# Add every binary that requires nvm, npm or node to run to an array of node globals
NODE_GLOBALS=(`find ~/.nvm/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)
NODE_GLOBALS+=("node")
NODE_GLOBALS+=("nvm")
# Lazy-loading nvm + npm on node globals call
load_nvm () {
export NVM_DIR=~/.nvm
[ -s "$(brew --prefix nvm)/nvm.sh" ] && . "$(brew --prefix nvm)/nvm.sh"
}
# Making node global trigger the lazy loading
for cmd in "${NODE_GLOBALS[#]}"; do
eval "${cmd}(){ unset -f ${NODE_GLOBALS}; load_nvm; ${cmd} \$# }"
done