70

I am trying to build a script in in which nvm and eventually node will get installed.
I have installed nvm with cURL. I see the modifications in the .profile or .bashrc file (both work) and when typing the nvm at the bash prompt, it shows the options available etc.
So nvm works. Manually I can install node, but as soon as I put the nvm command in a shell script:

nano test.sh

#!/bin/bash
nvm

and run it with:

chmod 755 test.sh
./test.sh

I get:

./test.sh: line 2: nvm: command not found

If it can't find nvm, I don't even have to think of

nvm ls-remote 

or

nvm install ...

I got Ubuntu 14.04 installed and Bash is my shell.

Anthon
  • 78,313
  • 42
  • 165
  • 222
okidoki
  • 703
  • 1
  • 5
  • 5

5 Answers5

111

nvm command is a shell function declared in ~/.nvm/nvm.sh.

You may source either of following scripts at the start of yours to make nvm() available:

. ~/.nvm/nvm.sh
. ~/.profile
. ~/.bashrc
. $(brew --prefix nvm)/nvm.sh  # if installed via Brew
  • 2
    HI, thanks. This makes sense then as nvm is "installed" in ~/.nvm. And is probably just a shell script. What I am missing though is that I can type nvm and get it to work, but when trying the shell scripts in ~/.nvm it doesn't work. – okidoki Feb 12 '15 at 17:42
  • what do you mean by `trying the shell scripts in ~/.nvm`? I explained how to run `nvm` from the shell script above. Is there anything unclear? – webknjaz -- Слава Україні Feb 12 '15 at 17:45
  • To elaborate my last comment. when I "sudo find / -iname nvm*" I find only things in my ~/.nvm folder. Executing the ~/.nvm/nvm-exec or ~/.nvm/nvm.sh (the only files in ~/.nvm, which turn out to be shell scripts) does not give me nvm, like just typing "nvm" on the command line. So where is the link between nvm and the program. – okidoki Feb 12 '15 at 17:47
  • Oh.. I guess `nvm` is an `alias` in your shell environment. Please post the output of `which nvm` and this will clear things out. – webknjaz -- Слава Україні Feb 12 '15 at 17:50
  • Hi webKnjaZ, this does not provide output... – okidoki Feb 12 '15 at 17:52
  • No output in the terminal where command `nvm` works? Then perhaps you could check `alias | grep nvm`. – webknjaz -- Слава Україні Feb 12 '15 at 17:57
  • Hi webKnjaZ, this does not provide output... But it looks like it is not an alias. The output of "compgen -a" does not include nvm, however "compgen -c | grep nvm" does. Meaning it is a command, but not an alias. – okidoki Feb 12 '15 at 17:59
  • 4
    I've installed `nvm` locally and made some research. `nvm` is a shell function declared in `nvm.sh`, so basically you just need to source it with `. ~/.nvm/nvm.sh` at the beginning of your script (or, as I wrote above, - source `.profile`/`.bashrc`) – webknjaz -- Слава Україні Feb 12 '15 at 18:02
  • webKnjaZ, you nailed it! I overlooked the fact that I needed to source ~/.nvm/nvm.sh before calling nvm within the test.sh script. Thanks a lot! – okidoki Feb 12 '15 at 18:06
  • I tried doing `. ~/.bashrc`, but `. ~/.nvm/nvm.sh` worked fine – zlog Apr 01 '16 at 11:04
  • . ~/.bashrc and source ~/.bashrc don't work. . ~/.nvm/nvm.sh works fine. haven't tried . ~/.profile – user137717 Jun 27 '16 at 16:39
  • @user137717 Why is `~/.bashrc` not working? Having the same problem. – Berkant İpek Jul 09 '20 at 09:44
  • Because you have to first add it there, or use bash in interactive mode. – webknjaz -- Слава Україні Jul 09 '20 at 09:45
3

If you installed it via brew on OSX, then you can load the brew sourced script into the script env by sourcing it as it details on the install.

I have this in projects to bootstrap them :

brew install nvm
. $(brew --prefix nvm)/nvm.sh
nvm install
...
IanVaughan
  • 177
  • 7
2

From all the answers here and in this related nvm issue I created this script (gist) that you can copy or clone (documentation is inlined):

# shellcheck shell=sh
# https://gist.github.com/karfau/dcf98c6eefc2f2132c160f5c14d2112f

# needs to be sourced as part of your script
# 1. tries to configure nvm and run `nvm install`
# 2. checks if the node version is correct based on ./.nvmrc (`v` prefix not supported)
# if both doesn't work, exits with code 1 and some helpful messages

# https://unix.stackexchange.com/a/184512/194420
# https://github.com/nvm-sh/nvm/issues/1290
if [ -f ~/.nvm/nvm.sh ]; then
  echo 'sourcing nvm from ~/.nvm'
  . ~/.nvm/nvm.sh
elif command -v brew; then
  # https://docs.brew.sh/Manpage#--prefix-formula
  BREW_PREFIX=$(brew --prefix nvm)
  if [ -f "$BREW_PREFIX/nvm.sh" ]; then
    echo "sourcing nvm from brew ($BREW_PREFIX)"
    . $BREW_PREFIX/nvm.sh
  fi
fi

if command -v nvm ; then
  nvm i
else
  echo "WARN: not able to configure nvm"
fi

NODE_VERSION="v$(cat .nvmrc)"
which node
ACTIVE_VERSION=$(node --version)
GLOBAL_NPM=$(which npm || echo "not found on PATH")
# .nvmrc can contain only major or major.minor or full version
# so we replace active version with node version and anything afterwards
# if something is left, it's not a match
if [ "${ACTIVE_VERSION%%$NODE_VERSION*}" ] || [ ! -e "$GLOBAL_NPM" ]; then
  echo "expected node '$NODE_VERSION' and npm on path"
  echo "but was '$ACTIVE_VERSION' and npm:'$GLOBAL_NPM'"
  exit 1
fi

Hope it helps Feedback on the gist or here is welcome.

PS: In the meantime I have updated the gist to use the NVM_DIR environment variable instead of the user directory to support custom installation sections added support for calling nvm use instead of nvm install.

karfau
  • 121
  • 5
  • `NODE_VERSION=$(cat .nvmrc)` this is enough in mac – Midhun G S Jan 28 '22 at 08:24
  • 1
    @MidhunGS this only works if the `.nvmrc` file contains the whole string as it is output by `node --version`: `v` prefix, major, minor and patch version. But the `nvm` also allows leaving out the `v` prefix, leaving out the patch version and leaving out the minor version. – karfau Jan 30 '22 at 19:48
0

Small callout on top of answer provided by @webKnjaZ: I had to source shell function for every command to make it work in my bash script. Something like this:

. ~/.nvm/nvm.sh --version
. ~/.nvm/nvm.sh install 4.4.5
0

Same thing happened to be below is the thing which worked for me:

root@ubuntu:/usr/src/playground# n=$(which node);n=${n%/bin/node}; chmod -R 755 $n/bin/*; sudo cp -r $n/{bin,lib,share} /usr/local

root@ubuntu:/usr/src/playground# sudo npm install express '/usr/src/playground/package.json' + [email protected] added 49 packages in 129.186s

The above command is a bit complicated, but all it's doing is copying whatever version of node you have active via nvm into the /usr/local/ directory (where user installed global files should live on a linux VPS) and setting the permissions so that all users can access them.