2

I have a script that runs some git and npm 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. The npm command runs and builds the files but throws lots of errors about

Node 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 tried env -i npm run build in the script and that just says env: ‘npm’: No such file or directory. So i then tried env -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 that env -i would give me clean env 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?

1

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 Ubuntu service 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 set LC_ALL=C.

  • I updated my answer with the result of changes. Note that i'm using su vs sudo 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 to npm run build as part of the process. – jtlindsey Feb 22 '18 at 4:38
  • 1
    @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 use su, you can use sudo 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? – Olorin Feb 22 '18 at 4:44
  • Fixed 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 – jtlindsey Feb 22 '18 at 4:46
  • Did you add anything to .profile, etc. for setting up npm? – Olorin Feb 22 '18 at 4:54
  • No, i used the nvm install and i checked both .profile and .bashrc of the user and there is nothing explicitly pointing to any v8 of node that i can see. – jtlindsey Feb 22 '18 at 4:59
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
  • Yep, nvm does rely on environment variables to do its work. I'd misread your comments, and thought you used npm somehow for this and not nvm. – Olorin Feb 22 '18 at 6:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.