See #1717 for installation details. Sorry if you already know these shell details - I had to review them to write this up.
Interactive shells are typed into. E.g. typing the command nvm at the flashing cursor.
This bug is about nvm not being available in non-interactive shells. E.g. this test.sh:
$ echo -e '#!/bin/bash \n nvm version' > test.sh
$ chmod +x test.sh
$ cat test.sh
#!/bin/bash
nvm version
$ ./test.sh
./test.sh: line 2: nvm: command not found
This is because nvm isn't on the path, which probably causes alot of other bugs.
Linking nvm.sh into the path doesn't work because nvm.sh doesn't appear to do anything when run directly:
./.nvm/nvm.sh version
<no output>
So, I'm a bit stuck on how to use nvm non-interactively and have to put this crufty code everywhere:
#/bin/bash
[ -s "$HOME/.nvm/nvm.sh" ] && source "$HOME/.nvm/nvm.sh" && nvm install
Which is kind of annoying. It would be nice if nvm was actually installed onto the path.
nvm.sh is not runnable, not a binary, never will show up in a PATH, and doesn't take a version argument. It's a sourced shell function. Try . ~/.nvm/nvm.sh.
@ljharb Hey Jordan, no problem. I get that. But it doesn't show up in non-interactive shells, so it can't be scripted. I noticed a nvm-exec file but didn't understand it's purpose.
What about a nvm file that sources nvm.sh and runs it with arguments?
The installer could link this into ~/bin or if no directory explain what to do.
I'd also like it to show up in non-interactive shells. In my example, I have a Docker image with NVM installed on a certain user. I'd like to start a new container and have NVM sourced when starting.
@MichaelJCole that's exactly what nvm-exec is for.
Aha! Great! Ok @ljharb , that's the same direction. For whatever reason, nvm-exec doesn't work for me in Zsh or Bash
nvm works great, but nvm-exec returns no output. Sunshine means command succeeded. Umbrella w/ rain means the command returned a failure code to the shell.
Am I using it wrong? Or did I miss some documentation?
michael@mcdesktop ~
☔ ls $NVM_DIR
alias Dockerfile Makefile package.json test
bash_completion install.sh nvm-exec README.md update_test_mocks.sh
CONTRIBUTING.md LICENSE.md nvm.sh ROADMAP.md versions
michael@mcdesktop ~
☀ bash $NVM_DIR/nvm-exec
michael@mcdesktop ~
☀ nvm
Node Version Manager
... (output truncated)
Note:
to remove, delete, or uninstall nvm - just remove the `$NVM_DIR` folder (usually `~/.nvm`)
michael@mcdesktop ~
☀ bash $NVM_DIR/nvm-exec
michael@mcdesktop ~
☀ ./$NVM_DIR/nvm-exec
zsh: no such file or directory: .//home/michael/.nvm/nvm-exec
michael@mcdesktop ~
☔ bash
michael@mcdesktop:~$ nvm
Node Version Manager
... (output truncated)
Note:
to remove, delete, or uninstall nvm - just remove the `$NVM_DIR` folder (usually `~/.nvm`)
michael@mcdesktop:~$ echo $NVM_DIR
/home/michael/.nvm
michael@mcdesktop:~$ .$NVM_DIR/nvm-exec
bash: ./home/michael/.nvm/nvm-exec: No such file or directory
michael@mcdesktop:~$ bash $NVM_DIR/nvm-exec
michael@mcdesktop:~$
That's because you're running bash $NVM_DIR/nvm-exec - nvm-exec is an executable. Try nvm-exec $version $command.
@ljharb I think nvm-exec is broken or not installing correctly. It doesn't seem to do anything in bash or zsh. nvm-exec ls-remote complained ls-remote wasn't a command. nvm-exec ls did a file listing.
michael@mcdesktop ~
☔ ./.nvm/nvm-exec ls
bin Desktop Documents Downloads Music NULL Pictures scm snap Templates Videos
@MichaelJCole that’s how it’s supposed to work. It takes an arbitrary command and executes it with a particular version of node nvm used.
@ljharb How do I use nvm in a non-interactive shell without having to source it each time?
I mean, really, you don't - one way or another, nvm.sh must be sourced to use nvm.
However, if you execute nvm-exec with the proper arguments, it will source it each time for you.
@ljharb ok, this isn't fitting my model, but that's ok.
For most projects, I've got a preview.sh or deploy.sh to start them up. Something like this for a hexo project:
#!/bin/bash
# Load nvm (node version manager), install node (version in .nvmrc), and npm install packages
[ -s "$HOME/.nvm/nvm.sh" ] && source "$HOME/.nvm/nvm.sh" && nvm use
# Use local-npm if running
wget -qO /dev/null 'http://127.0.0.1:5080/_browse/' && npm set registry http://127.0.0.1:5080 && echo '----> local-npm found <----'
# Npm install if not already.
[ ! -d "node_modules" ] && npm install
hexo server
Looking at this again, I'm whining about the first parts of the first line. So maybe not a big deal. Mostly, it's not very new developer friendly.
Do you have any suggestions or do you see a better way? Thanks!
I don't think there's a better way, no (altho the && nvm use is redundant; nvm auto-runs that for you).
Ok, cool. Thanks!
I would like to use "nvm use" in my cron scripts and am unable to run it. Neither nvm-exec nor nvm.sh are working...
~/.nvm/nvm.sh use v11
^ does nothing and does not switch to version 11...
~/.nvm/nvm-exec use v11
^ outputs the error: "/home/ubuntu/.nvm/nvm-exec: line 15: exec: use: not found"
@ljharb what's the correct way to do this?
@JimLynchCodes your cron scripts need to source nvm.sh to be able to use nvm.
To run nvm use via ssh remote command as part of a deployment script doing as ljharb commented makes it work.
source ~/.nvm/nvm.sh
nvm use v12.4.0
sshCommands="$(cat <<END_HEREDOC
# Install api server dependencies.
source ~/.nvm/nvm.sh
echo "Switching to appropriate node.js version using nvm"
if ! nvm use v12.4.0 ; then
echo "Error using nvm to switch node.js version."
exit 14
fi
echo "Installing server api dependencies"
if ! yarn ; then
echo "Error installing server api dependencies."
#exit 15
fi
END_HEREDOC
)"
ssh ${deploymentUsername}@${deploymentHost} -t "$sshCommands"
Most helpful comment
@ljharb How do I use nvm in a non-interactive shell without having to source it each time?