nvm
nvm copied to clipboard
nvm install crashes bash script when bash is set to exit on error
-
Operating system and version: OSX 10.11.6
-
How did you install
nvm? (e.g. install script in readme, Homebrew): curl -
What steps did you perform?
I ran this script:
Marks-MacBook-Pro:tmp marksmith$ cat /tmp/nvm_exit_on_error_issue.sh
#!/usr/bin/env bash
set -e; set -o pipefail
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
nvm install stable
echo "done"
exit 0
- What happened?
Marks-MacBook-Pro:tmp marksmith$ /tmp/nvm_exit_on_error_issue.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13226 100 13226 0 0 3637 0 0:00:03 0:00:03 --:--:-- 3637
=> Downloading nvm from git to '/Users/marksmith/.nvm'
=> Cloning into '/Users/marksmith/.nvm'...
remote: Enumerating objects: 278, done.
remote: Counting objects: 100% (278/278), done.
remote: Compressing objects: 100% (249/249), done.
remote: Total 278 (delta 33), reused 88 (delta 16), pack-reused 0
Receiving objects: 100% (278/278), 142.36 KiB | 65.00 KiB/s, done.
Resolving deltas: 100% (33/33), done.
=> Compressing and cleaning up git repository
=> nvm source string already in /Users/marksmith/.bash_profile
=> bash_completion source string already in /Users/marksmith/.bash_profile
=> Close and reopen your terminal to start using nvm or run the following to use it now:
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
The script doesn't complete.
Now comment out the exit on error line and run again:
Marks-MacBook-Pro:tmp marksmith$ vim /tmp/nvm_exit_on_error_issue.sh
Marks-MacBook-Pro:tmp marksmith$ cat /tmp/nvm_exit_on_error_issue.sh | grep pipe
#set -e; set -o pipefail
Marks-MacBook-Pro:tmp marksmith$ unset NVM_DIR; rm -rf ~/.nvm
Marks-MacBook-Pro:tmp marksmith$ /tmp/nvm_exit_on_error_issue.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 13226 100 13226 0 0 5546 0 0:00:02 0:00:02 --:--:-- 5545
=> Downloading nvm from git to '/Users/marksmith/.nvm'
=> Cloning into '/Users/marksmith/.nvm'...
remote: Enumerating objects: 278, done.
remote: Counting objects: 100% (278/278), done.
remote: Compressing objects: 100% (249/249), done.
remote: Total 278 (delta 33), reused 88 (delta 16), pack-reused 0
Receiving objects: 100% (278/278), 142.36 KiB | 68.00 KiB/s, done.
Resolving deltas: 100% (33/33), done.
=> Compressing and cleaning up git repository
=> nvm source string already in /Users/marksmith/.bash_profile
=> bash_completion source string already in /Users/marksmith/.bash_profile
=> Close and reopen your terminal to start using nvm or run the following to use it now:
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
Downloading and installing node v12.7.0...
Downloading https://nodejs.org/dist/v12.7.0/node-v12.7.0-darwin-x64.tar.gz...
######################################################################## 100.0%
Computing checksum with shasum -a 256
Checksums matched!
Creating default alias: default -> stable (-> v12.7.0)
done
The script completes.
- What did you expect to happen?
The script to complete in both cases.
- Is there anything in any of your profile files (
.bashrc,.bash_profile,.zshrc, etc) that modifies thePATH?
Only .bash_profile has the nvm loading code from the installation guide.
Is it the e or the o option? What happens if you set one and not the other?
Setting only the e option fails, setting only the o option completes.
Could you set -x and provide a gist of the output? It might help me figure out which command is exiting.
Do note - the bash that comes with the Mac has a bug that means that legitimate tests can cause -e to exit - if that's the case, there is no workaround here except to not set -e in the first place (a mode that bash experts consistently advise should never be set).
@ljharb I will run it again with -x when I get a chance - having a few laptop issues today - the short minimal example script is in the original post if you want to try it yourself.
I was actually running with the stock mac bash (the real code is a setup script that among other things upgrades bash to latest version), so your point about bash version is interesting. I’ll test with a more recent bash when I get a chance.
I did a quick google search to find opinions from bash experts about set -e, didn’t find anything. I don’t see why exiting a script when something errors would be a bad thing, why is set -e considered bad?
See https://mywiki.wooledge.org/BashFAQ/105 - basically, it’s a poor imitation of explicitly checking each command for failure.
Oh my days, what a can of worms, thanks for the link.
The set -x output can still help; if it’s something i can fix, i will.
Thanks, here's the gist with set -x output
hmm, that suggests it's failing on an nvm_echo which is just a wrapped printf. That doesn't make much sense.
Is there some other info that would be helpful? The bash version is:
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
With set -e; set -x, what happens if you run [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use?
It completes successfully:
/tmp $ cat nvm-test.sh
#!/usr/bin/env bash
set -e; set -x
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use
/tmp $ ./nvm-test.sh
+(nvm-test.sh:4): '[' -s /Users/marksmith/.nvm/nvm.sh ']'
+(nvm-test.sh:4): . /Users/marksmith/.nvm/nvm.sh --no-use
++(nvm.sh:13): NVM_SCRIPT_SOURCE=']'
++(nvm.sh:249): '[' -z '' ']'
++(nvm.sh:250): export NVM_CD_FLAGS=
++(nvm.sh:250): NVM_CD_FLAGS=
++(nvm.sh:252): nvm_is_zsh
++(nvm.sh:16): nvm_is_zsh(): '[' -n '' ']'
++(nvm.sh:257): '[' -z /Users/marksmith/.nvm ']'
++(nvm.sh:268): case $NVM_DIR in
++(nvm.sh:276): unset NVM_SCRIPT_SOURCE
++(nvm.sh:3584): nvm_process_parameters --no-use
++(nvm.sh:3569): nvm_process_parameters(): local NVM_AUTO_MODE
++(nvm.sh:3570): nvm_process_parameters(): NVM_AUTO_MODE=use
++(nvm.sh:3571): nvm_process_parameters(): nvm_supports_source_options
+++(nvm.sh:3499): nvm_supports_source_options(): . /dev/stdin yes
+++(nvm.sh:3499): nvm_supports_source_options(): nvm_echo '[ $# -gt 0 ] && nvm_echo $1'
+++(nvm.sh:20): nvm_echo(): command printf '%s\n' '[ $# -gt 0 ] && nvm_echo $1'
++(nvm.sh:3499): nvm_supports_source_options(): '[' _yes = _yes ']'
++(nvm.sh:3572): nvm_process_parameters(): '[' 1 -ne 0 ']'
++(nvm.sh:3574): nvm_process_parameters(): case "$1" in
++(nvm.sh:3576): nvm_process_parameters(): NVM_AUTO_MODE=none
++(nvm.sh:3578): nvm_process_parameters(): shift
++(nvm.sh:3572): nvm_process_parameters(): '[' 0 -ne 0 ']'
++(nvm.sh:3581): nvm_process_parameters(): nvm_auto none
++(nvm.sh:3539): nvm_auto(): local NVM_CURRENT
+++(nvm.sh:3540): nvm_auto(): nvm_ls_current
+++(nvm.sh:844): nvm_ls_current(): local NVM_LS_CURRENT_NODE_PATH
++++(nvm.sh:845): nvm_ls_current(): command which node
+++(nvm.sh:845): nvm_ls_current(): NVM_LS_CURRENT_NODE_PATH=/Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
++++(nvm.sh:847): nvm_ls_current(): nvm_version_dir iojs
++++(nvm.sh:371): nvm_version_dir(): local NVM_WHICH_DIR
++++(nvm.sh:372): nvm_version_dir(): NVM_WHICH_DIR=iojs
++++(nvm.sh:373): nvm_version_dir(): '[' -z iojs ']'
++++(nvm.sh:373): nvm_version_dir(): '[' iojs = new ']'
++++(nvm.sh:375): nvm_version_dir(): '[' _iojs = _iojs ']'
++++(nvm.sh:376): nvm_version_dir(): nvm_echo /Users/marksmith/.nvm/versions/io.js
++++(nvm.sh:20): nvm_echo(): command printf '%s\n' /Users/marksmith/.nvm/versions/io.js
+++(nvm.sh:847): nvm_ls_current(): nvm_tree_contains_path /Users/marksmith/.nvm/versions/io.js /Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:279): nvm_tree_contains_path(): local tree
+++(nvm.sh:280): nvm_tree_contains_path(): tree=/Users/marksmith/.nvm/versions/io.js
+++(nvm.sh:281): nvm_tree_contains_path(): local node_path
+++(nvm.sh:282): nvm_tree_contains_path(): node_path=/Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:284): nvm_tree_contains_path(): '[' @/Users/marksmith/.nvm/versions/io.js@ = @@ ']'
+++(nvm.sh:284): nvm_tree_contains_path(): '[' @/Users/marksmith/.nvm/versions/node/v12.8.0/bin/node@ = @@ ']'
+++(nvm.sh:289): nvm_tree_contains_path(): local pathdir
++++(nvm.sh:290): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:290): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node/v12.8.0/bin
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0/bin
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node/v12.8.0
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users '!=' /Users/marksmith/.nvm/versions/io.js ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/
+++(nvm.sh:291): nvm_tree_contains_path(): '[' / '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' / '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' / '!=' / ']'
+++(nvm.sh:294): nvm_tree_contains_path(): '[' / = /Users/marksmith/.nvm/versions/io.js ']'
+++(nvm.sh:849): nvm_ls_current(): nvm_tree_contains_path /Users/marksmith/.nvm /Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:279): nvm_tree_contains_path(): local tree
+++(nvm.sh:280): nvm_tree_contains_path(): tree=/Users/marksmith/.nvm
+++(nvm.sh:281): nvm_tree_contains_path(): local node_path
+++(nvm.sh:282): nvm_tree_contains_path(): node_path=/Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:284): nvm_tree_contains_path(): '[' @/Users/marksmith/.nvm@ = @@ ']'
+++(nvm.sh:284): nvm_tree_contains_path(): '[' @/Users/marksmith/.nvm/versions/node/v12.8.0/bin/node@ = @@ ']'
+++(nvm.sh:289): nvm_tree_contains_path(): local pathdir
++++(nvm.sh:290): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0/bin/node
+++(nvm.sh:290): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node/v12.8.0/bin
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0/bin '!=' /Users/marksmith/.nvm ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0/bin
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node/v12.8.0
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node/v12.8.0 '!=' /Users/marksmith/.nvm ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node/v12.8.0
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions/node
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions/node '!=' /Users/marksmith/.nvm ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions/node
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm/versions
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm/versions '!=' /Users/marksmith/.nvm ']'
++++(nvm.sh:292): nvm_tree_contains_path(): dirname /Users/marksmith/.nvm/versions
+++(nvm.sh:292): nvm_tree_contains_path(): pathdir=/Users/marksmith/.nvm
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' '' ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' . ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' / ']'
+++(nvm.sh:291): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm '!=' /Users/marksmith/.nvm ']'
+++(nvm.sh:294): nvm_tree_contains_path(): '[' /Users/marksmith/.nvm = /Users/marksmith/.nvm ']'
+++(nvm.sh:850): nvm_ls_current(): local VERSION
++++(nvm.sh:851): nvm_ls_current(): node --version
+++(nvm.sh:851): nvm_ls_current(): VERSION=v12.8.0
+++(nvm.sh:852): nvm_ls_current(): '[' v12.8.0 = v0.6.21-pre ']'
+++(nvm.sh:855): nvm_ls_current(): nvm_echo v12.8.0
+++(nvm.sh:20): nvm_echo(): command printf '%s\n' v12.8.0
++(nvm.sh:3540): nvm_auto(): NVM_CURRENT=v12.8.0
++(nvm.sh:3541): nvm_auto(): local NVM_MODE
++(nvm.sh:3542): nvm_auto(): NVM_MODE=none
++(nvm.sh:3543): nvm_auto(): local VERSION
++(nvm.sh:3544): nvm_auto(): '[' _none = _install ']'
++(nvm.sh:3551): nvm_auto(): '[' _none = _use ']'
++(nvm.sh:3562): nvm_auto(): '[' _none '!=' _none ']'
/tmp $ echo $?
0
Seems like less output than usual, what does the --no-use option do?
it skips the automatic nvm use call.
After no-use, with set -e, can you then run nvm use successfully?
Yes - however I'm not sure how this has any effect on the issue I am having...using --no-use in my original test script, the nvm install stable command still hangs.
ok - nvm install also calls nvm use, so I’d suspect that’s the part that errors.
Just to clarify, this script completes successfully:
#!/usr/bin/env bash
set -e; set -x
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use
nvm use stable
Could you clarify what you are thinking? Since nvm use is working, doesn't that suggest that the issue is actually not with nvm use?
[updated - added question]
I ran into this issue, and if I'm reading this correctly, it looks like the script fails on checking if a specific version of nvm is installed: https://github.com/nvm-sh/nvm/blob/v0.38.0/nvm.sh#L1186 - it looks like this nvm_is_version_installed() is a command that's made to execute and fail.
Output - https://gist.github.com/jrjurman-jellyfish/e264816793cefa5fcb85a560553050cb
@jrjurman-jellyfish which version of nvm? We now re-invoke nvm with +e, so this shouldn’t be an issue.
We're using 0.38.0, I believe based on my testing I was also getting this issue with the latest version
We've done this for a long time: https://github.com/nvm-sh/nvm/blob/v0.36.0/nvm.sh#L2362-L2368, and it goes older.