Use aliases with exec in a non-interactive shell - node.js

During a deployment process I run yarn install over an SSH connection in a non-interactive shell. Since an alternative node.js version (default version 8.x on the server is too low) must be used, an alias is created and loaded in the bash script over the SSH connection:
shopt -s expand_aliases
source ~/.bashrc
node -v
The .bashrc script looks like:
export PATH=/opt/plesk/node/12/bin/node:$PATH
alias node="/opt/plesk/node/12/bin/node"
Running node -v will print the correct version 12.x. The correct version is also output when executing JavaScript code:
node -e "console.log(process.versions.node);"
But yarn calls node internally with exec (https://github.com/yarnpkg/yarn/blob/master/bin/yarn#L20). And this will call the default version of node instead of the alias version. That means yarn versions lists node 8.x.
This is only the case with a non-interactive bash. If I call this in an interactive shell, yarn internally uses the correct node version 12.x of the alias.
How can I run yarn in a non-interactive bash with the correct node version?

Related

Set node version for a single command using nvm

I have a command that must be run with Node 16 installed, no other version. However, I need to have the latest version of Node installed for regular use.
How can I configure things, perhaps with environment variables, so that just that one command uses Node 16?
Something like nvm use 16 && node -v && nvm use 19 is too slow, but aliasing in .zshrc is an option.
What I've done in one of my Projects is this:
I've switched to node 16: nvm use 16.
After that which node showed this path: /root/.nvm/versions/node/v16.19.0/bin/node
So I've simply created a symlink for this executable: ln -s $(which node) /usr/bin/node16
Finally I switched back the version: nvm use system
Now you can use your default node Version with node and the desired node-version for this command with node16.

Node version inconsistent in crontab

I regularly at version 8.4.0, then I installed nvm and used it to upgrade to version 9.11.1.
When running the terminal, I have version 9.11.1, however if a conjob runs a script, node 8.4.0 is still used.
The same ec2-user is running the cron so for me it is strange that the user ec2-user has version 9.11.1 if used via shell and 8.4.0 if used via cron.
How can I resolve this to always use 9.11.1?
You are most likely using just node or /usr/local/bin/node to refer to node, instead of /usr/.nvm/versions/node/v9.11.1/bin/node

How can I call "nvm use" in a bash script, and have the selected node version retained after the script executes?

For a build process that requires updating from Node.js 12 to 14, I'd like a bash script to detect whether nvm is installed, and, if so, do nvm use v14 (or nvm install v14 if necessary), and then I want the nvm-selected node version to stick at 14 after the bash script terminates, not just for the duration of the script.
I can switch to v14 with this script, but after the script has terminated, the shell environment remains at v12:
#!/bin/bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
source ~/.bashrc
nvm --version
echo $NVM_BIN
node --version
nvm use v14
echo $NVM_BIN
node --version
Just executing the nvm command in a bash script is a pain because nvm isn't a true command, but a shell function, and the script has to use the first three lines to set up nvm for the script.
The output is:
0.33.11
/home/pi/.nvm/versions/node/v12.21.0/bin
v12.21.0
Now using node v14.16.0 (npm v6.14.11)
/home/pi/.nvm/versions/node/v14.16.0/bin
v14.16.0
When the script is finished, however:
I think the trick might be making sure the environment variable NVM_BIN persists at the v14 path when the script exits, but I don't know how to do that. In fact, I think it's generally not allowed for the shell in which a script executes to change environment variables in the parent shell.
The nvm commmand, however, is itself a shell script, and whatever it does is persistent after it's done executing. There should be some way for me to make this happen too.
I think if you set an alias with nvm for default,
nvm alias default 14.0.0
the node version will persist across any new terminal instances.
To have the selected node version after the script executes you can run it like this:
. change-node-version.sh
script
node --version
nvm use 14.18.0
node --version
then:
node --version
➜ v14.18.0

The problem with running version managed Node as a remote SSH script

My question is about nvm but it may relate to other Node version manages like n or nvs.
You probably a;ready know that you can run remote programs with SSH like this:
ssh user#server COMMAND
For example the command can be the Node.js script:
ssh user#devserver 'node ~/getstats'
The problem is that it will not work for Node that was installed using nvm. Why? Because node is actually an alias to something like /home/user/.nvm/versions/node/v12.1.0/bin/node. The alias is installed in ~/.bashrc which is run when you login with SSH. But when you execute remote command with ssh SERVER COMMAND environment scripts are not run because the shell runs in a restricted mode.
One work around is to create ~/node which containts /home/monitor/.nvm/versions/node/v12.1.0/bin/node * and is executable, then you can do ssh SERVER './node SCRIPT'. But this is not perfect because once you upgrade Node the path will change and you will need to update this file as well.
What would be the recommended way to solve the problem with running version managed Node as a remote SSH script?
Try this:
ssh user#devserver '. ~/.nvm/nvm.sh && node ~/getstats'
Note that by default, .bashrc in Ubuntu 18.04 has the following:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
Have you tried to run sss user#host nvm run node ~/getstats ?

How to configure user environment to use the latest node runtime

We initialize node.js using nvm use 0.10.0
How to configure user environment to use the latest node runtime, so that the bash shell gets initialized when I launch a new terminal in Ubuntu
posting this answer for future reference and help.
1st run the following command in the bash.
nvm alias default <the default version you want to set>
then put this in your .bashrc
export NVM_DIR="path/to/.nvm/folder" #<-edit with real value
if [ -s "$NVM_DIR/nvm.sh" ]; then
source "$NVM_DIR/nvm.sh"
fi
NODE_DEFAULT_VERSION=$(<"$NVM_DIR/alias/default")
export PATH="$NVM_DIR/versions/node/$NODE_DEFAULT_VERSION/bin":$PATH
and, source .bashrc
the advantage of this setup is that, whatever node you will install and set as default, it will be available for all bash sessions.
You could put this in your ~/.bashrc:
nvm use 0.10.0

Resources