次のようなユーザーに基づいていくつかの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と環境に関するエラーをスローします。ターミナルからユーザーとしてコマンドを実行するときとは何かが異なるかのようです。
このコマンドが正しく機能しない理由は何ですか?
ノードエラーを確認するというオロリンの提案に従って、私はそれをさらに調査しました。 someuser
のnode -v
が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
env
ではソースなしでは利用できず、npm run build
はnvm
を参照する必要があります。
奇妙な問題で、一部のユーザーがnvm
のbash
リソースを this thread に基づいて使用すると、同様の問題に遭遇したようです。 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
env -i
は環境をクリーンアップします。これにはPATH
変数が含まれます。これは、フルパスを指定しない場合にコマンドを検索するために使用されます。したがって、env -i
、呼び出すコマンドへのフルパスを指定する必要があります。 npm
を使用すると、npm
自体が#! /usr/bin/env node
はシバンなので、node
コマンドの検索は失敗します。
環境をクリーンアップする必要がある場合は、次のいずれかを試してください。
Sudo -iu someuser sh -c "...."
su someuser - -c "...."
(これらのコマンドはどちらも、環境のクリーンアップを行ってログインシェルを起動します)または、env
を使用して、Ubuntu service
コマンドのように、いくつかの環境変数を保持します。
$ 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
、そしておそらくLC_ALL=C
。