web-dev-qa-db-ja.com

sudoを介してnvm(bash関数)を実行します

基本的に実行する必要があるinitスクリプトを書きたい

nvm use v0.11.12 && forever start /srv/index.js

ユーザーとしてwebconfignvmは、~webconfig/.nvm/nvm.shで宣言されているシェル関数であり、webconfigsource ~/.nvm/nvm.sh.bashrcを介して含まれています。

私は以下を試しました:

Sudo -H -i -u webconfig nvm

echo "nvm" | Sudo -H -i -u webconfig

しかし、彼らは失敗します

-bash:nvm:コマンドが見つかりません
-bash:1行目:nvm:コマンドが見つかりません

Sudo -H -i -u webconfigを実行してそのシェルに手動でnvmと入力すると、機能します。私は何が間違っているのですか?

4
Yogu

ここでの問題は、よくあることですが、さまざまなタイプのシェルに関するものです。

  • ターミナルエミュレータ(たとえば、gnome-terminal)を開くと、インタラクティブ、非ログインシェルと呼ばれるものが実行されます。

  • コマンドラインからマシンにログインするか、su usernameSudo -u usernameなどのコマンドを実行すると、対話型ログインシェルが実行されます。

したがって、開始したシェルのタイプに応じて、異なるスタートアップファイルのセットが読み取られます。 man bashから:

   When  bash is invoked as an interactive login Shell, or as a non-inter‐
   active Shell with the --login option, it first reads and executes  com‐
   mands  from  the file /etc/profile, if that file exists.  After reading
   that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile,
   in  that order, and reads and executes commands from the first one that
   exists and is readable.  The --noprofile option may be  used  when  the
   Shell is started to inhibit this behavior.

つまり、~/.bashrcはログインシェルによって無視されます。 Sudoに対して-iオプションを使用しているため、ユーザーのログインシェルのスタートアップファイルが(man Sudoから)読み取られています。

 -i, --login
             Run the Shell specified by the target user's password data‐
             base entry as a login Shell.  This means that login-specific
             resource files such as .profile or .login will be read by the
             Shell. 

だから、あなたができることは

  1. 代わりに、ユーザーの~/.profileまたは~/.bash_profileで関数を定義してください。 ~/.profileが存在する場合、~/.bash_profileは無視されることに注意してください。また、~/.bash_profileはbash固有であるため、代わりに.profileを使用しますが、~/.bash_profileが存在しないことを確認してください。

  2. ソース~/.nvm/nvm.sh from ~/.profile

6
terdon

@ terdon はすでにこれについていくつかの良い詳細を追加しているので、ここでは繰り返しません。言い換えると、問題の原因は、bashがログインシェルとして呼び出されたときに.bashrcを自動的に取得せず、代わりに~/.bash_profile~/.bash_login、または~/.profileのみ。

これらのプロファイルファイルの1つにコードを追加して、.bashrcを取得するのが一般的な方法です。デフォルトでは、~/.profileに次のコードがあります。

if [ "$BASH" ]; then
  if [ -f ~/.bashrc ]; then
    . ~/.bashrc
  fi
fi

更新

以下のコメントから、最善の解決策はおそらく[ -z "$PS1" ] && returnから.bashrc行を削除し、他のすべてをそのままにしておくことだと思います。

4
Graeme
Sudo -Hu webconfig bash -c '. ~/.nvm/nvm.sh && nvm'
1