Nvm: How does NVM works in non-interactive non-login shell?

Created on 27 Jan 2019  路  8Comments  路  Source: nvm-sh/nvm

Sorry that, the question got created (half way) when I pressed enter by mistake.

@ljharb mentioned at Issue 1959
that nvm doesn鈥檛 require an interactive shell, but it does require a login shell.

But how does it work in a non-interactive shell given that only in .bashrc where nvm script is sourced, is not read for a non-interactive shell.

You said that a login shell is required. npm cli global packages are defined only if nvm is defined. I have used the command from these global packages in a non interactive non login script. But it seems to be working.

I need to understand that because, I am trying out something.

needs followup

Most helpful comment

A login shell is required only because that way, the right profile files will be auto-sourced.

You can . $NVM_DIR/nvm.sh in any shell, and nvm should become available.

All 8 comments

Do you have a specific question?

nvm should work fine in a non-interactive shell, since there's nothing that requires interaction in it.

A login shell is required only because that way, the right profile files will be auto-sourced.

You can . $NVM_DIR/nvm.sh in any shell, and nvm should become available.

nvm is a sourced shell function; in a subshell, sourced shell functions like nvm should still be available.

Is there a specific issue you're having, or are you only asking theoretically?

Hi I am really having issues with nvm taking lot of time, when the bashrc loads. I have been folllowing the discussion on this issue.

As suggested by users, I modified my bashrc with the following

if [ -s "$HOME/.nvm/nvm.sh" ] && [ ! "$(type -f __init_nvm)" = function ]; then
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
    declare -a __node_commands=(nvm `find -L $NVM_DIR/versions/*/*/bin -type f -exec basename {} \; | sort -u`)
    function __init_nvm() {
        for i in "${__node_commands[@]}"; do unalias $i; done
        . "$NVM_DIR"/nvm.sh
        unset __node_commands
        unset -f __init_nvm
    }
    for i in "${__node_commands[@]}"; do alias $i='__init_nvm && '$i; done
fi

This works perfectly while working interactively. As it takes some time only at the first time when npm or package binaries are invoked.

But this doesn't work inside a script. I really like this solution but I have some scripts which use npm binaries inside them.

Could you please suggest any changes that I could make. Also invoking . $NVM_DIR/nvm.sh takes a lot of time.

Basically, I don't use nvm much. I installed it as it is recommended by npm to avoid using sudo. I am usually not concrened with varoious node version. In this case can I just export Path="/home/nikhil/.nvm/versions/node/v10.15.0/bin/:$PATH" in my.bashrc`? Will this work in a script?

In a script, explicitly run nvm use, or source nvm.sh with --no-use.

Manually setting the PATH is not something I'd recommend.

May I ask you why do you recommend so? And why don't you recommend setting the PATH?

By setting the PATH, package (global) binaries could be run, without sourcing the script.

Typically compiled executable sources are set on the PATH if I'm not mistaken. NVM is just run by a shell script, so it doesn't make much sense to put it on the PATH.

However, I've seen batch scripts appended to the PATH in Windows environments, so maybe I'm just completely off-keel.

@anishmittal2020 nvm is just a sourced shell function; it puts node and npm on the PATH, is all.

If you run nvm use, the PATH is set - and global binaries can be run in any shell, even without nvm available, as long as you preserve the PATH. However, manually setting it is brittle.

Was this page helpful?
0 / 5 - 0 ratings