Bash script not handling npm commands correctly
Solution 1
Per Olorin's suggestion to look at the node error, I explored that more. Despite the fact that node -v
for someuser
was returning v9.4.0
and the locate
command not finding any v8
versions installed for any user, and having re-installed node
, i was still getting the same error. The following command works. Note the source ~/.nvm/nvm.sh;
#!/bin/sh
/bin/su tstapps -c "
cd /opt/app1/;
git remote update;
git pull origin dev;
cd /opt/app1/client/;
source ~/.nvm/nvm.sh;
npm run build;
At one point I had nvm use v9.5.0
and then tested it still works without it. Next I removed source ~/.nvm/nvm.sh;
and it was broken again. So apparently the nvm
isn't available in shell-scripts
env
without sourcing it and the npm run build
needs to see nvm
.
Strange issue and looks like some users ran into similar issues with using nvm
resources in bash
based on this thread. Still not sure where it was getting the v8
from. Unless it was getting v8
from the include/node
directory of v9
installations. Example:
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-platform.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-profiler.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-testing.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-util.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-value-serializer-version.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-version-string.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8-version.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8.h
/home/someuser/.nvm/versions/node/v9.5.0/include/node/v8config.h
Solution 2
env -i
cleans the environment, and that includes the PATH
variable, which is used to look up commands if you don't give the full path. So, with env -i
, you need to specify the full path to commands being invoked. With npm
, what probably happens is that npm
itself is a script which has #! /usr/bin/env node
as the shebang, so the lookup for the node
command fails.
If you need to clean the environment, try either of:
sudo -iu someuser sh -c "...."
-
su someuser - -c "...."
(both these commands start login shells with some cleaning of the environment) -
or, with
env
, retain some environment variables, like the Ubuntuservice
command does:$ grep env $(command -v service) -m1 out=$(env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status 2>&1)
You probably don't need all those, but keep
$PATH
,$TERM
, and maybe setLC_ALL=C
.
Related videos on Youtube
jtlindsey
Hello, My name is Travis. Im on the web at jtlindsey.com
Updated on September 18, 2022Comments
-
jtlindsey over 1 year
I have a script that runs some
git
andnpm
commands based on a user like#!/bin/sh /bin/su someuser -c " cd /opt/app1/; env -i git remote update; env -i git pull origin dev; cd /opt/app1/client/; npm run build; "
The
git
commands run correctly. Thenpm
command runs and builds the files but throws lots of errors aboutNode Sass could not find a binding for your current environment: Linux 64-bit with Node.js 8.x Found bindings for the following environments: - Linux 64-bit with Node.js 9.x This usually happens because your environment has changed since running `npm install`. Run `npm rebuild node-sass --force` to build the binding for your current environment.
If I run
npm run build
as the user from terminal, everything builds fine. I even triedenv -i npm run build
in the script and that just saysenv: ‘npm’: No such file or directory
. So i then triedenv -i /usr/local/bin/npm run build
and oddly that returned/usr/bin/env: 'node': No such file or directory
.I though that the
user -c
would set me up with all env like the user was logged in and thatenv -i
would give me cleanenv
without the parent.also tried:
#!/bin/sh /bin/su someuser - -c " cd /opt/app1/; git remote update; git pull origin dev; cd /opt/app1/client/; npm run build; "
That last attempt returns same as first: git commands work, build throws errors about sass and environment as if something is different than when i run the command as the user from the terminal.
Any idea why this command is not working correctly?
-
jtlindsey about 6 yearsI updated my answer with the result of changes. Note that i'm using
su
vssudo
because i need any user that is part of the group that can run that command to be able to run it without sudo and without a password. The command worked great until we needed tonpm run build
as part of the process. -
Olorin about 6 years@jtlindsey I don't understand what you mean by the part where you say "because ... without a password". It's easy to setup NOPASSWD rules with
sudo
, and if you can usesu
, you can usesudo
for that. Also, in the edit,env
without any options is meaningless, you might as well run the commands without it. Note how the output says that it expected Node 8.x and got 9.x. How did you install/setup Node 8.x for your user? -
jtlindsey about 6 yearsFixed last edit. For the install, I logged in as the user and did npm install and then confirmed all npm commands worked from command line before logging out. So i'm not sure how a v8 is showing up. Node legacy is not installed and the user node env is v9
-
Olorin about 6 yearsDid you add anything to
.profile
, etc. for setting up npm? -
jtlindsey about 6 yearsJust did a locate command to see where any v8 node might be and removed all of them (nvm leave behind previous versions). Then i removed node modules, did
npm install
again to re-install modules, and same issue.npm run build
works if i do it from terminal but it breaks in the middle of the build process when run from script. At this point i don't know where it is getting the v8 from becauselocate
doesn't find v8 anywhere anymore. -
Olorin about 6 yearsYep,
nvm
does rely on environment variables to do its work. I'd misread your comments, and thought you usednpm
somehow for this and notnvm
.