Bash 脚本无法正确处理 npm 命令

Bash 脚本无法正确处理 npm 命令

我有一个脚本,可以根据用户运行一些命令,git例如npm

#!/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;
"

命令git运行正确。该npm命令运行并构建文件,但抛出很多错误

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.

如果我npm run build从终端以用户身份运行,一切都会正常。我什至env -i npm run build在脚本中尝试过,结果就是这样env: ‘npm’: No such file or directory。所以我然后尝试了env -i /usr/local/bin/npm run build,奇怪的是又回来了/usr/bin/env: 'node': No such file or directory

我认为这user -c会给我设置所有环境,就像用户登录一样,这env -i会让我env在没有父母的情况下干净。

还尝试过:

#!/bin/sh
/bin/su someuser - -c "
cd /opt/app1/;
git remote update;
git pull origin dev;
cd /opt/app1/client/;
npm run build;
"

最后一次尝试返回的结果与第一次相同: git 命令有效,构建会抛出有关 sass 和环境的错误,就好像我从终端以用户身份运行命令时有所不同。

知道为什么这个命令不能正常工作吗?

答案1

根据 Olorin 建议查看节点错误,我对此进行了更多探索。尽管事实上node -vforsomeuser正在返回v9.4.0并且该locate命令没有找到v8为任何用户安装的任何版本,并且重新安装了node,但我仍然遇到相同的错误。以下命令有效。请注意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;

有一次我nvm use v9.5.0已经测试过它在没有它的情况下仍然可以工作。接下来我把它取下来source ~/.nvm/nvm.sh;,它又坏了。所以显然,如果没有采购它并且需要查看,nvm就无法获得它。shell-scripts envnpm run buildnvm

奇怪的问题,看起来有些用户在使用基于的nvm资源时遇到了类似的问题bash这个线程。仍然不确定它是v8从哪里得到的。除非它是v8从安装include/node目录中获取的v9。例子:

/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

答案2

env -i清理环境,其中包括PATH变量,如果您不提供完整路径,则该变量用于查找命令。因此,使用 时env -i,您需要指定所调用命令的完整路径。对于npm,可能发生的情况是它npm本身是一个具有 shebang 的脚本#! /usr/bin/env node,因此命令的查找node失败。

如果您需要清洁环境,请尝试以下任一方法:

  • sudo -iu someuser sh -c "...."
  • su someuser - -c "...."(这两个命令都会启动登录 shell,并对环境进行一些清理)
  • 或者,使用env,保留一些环境变量,就像 Ubuntuservice命令所做的那样:

    $ 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)
    

    您可能不需要所有这些,但保留$PATH, $TERM,也许还需要 set LC_ALL=C

相关内容