web-dev-qa-db-ja.com

su -cを使用すると、どのファイルがソースになりますか?

コンテキスト

Ubuntu LTS 14.04に取り組んでいます。 rootユーザーとしてログインしています。次のコマンドを実行します。

exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"

そのため、「simple_user_service」は、root権限ではなく「simple_user」権限で起動されます。

質問

「exec su simple_user -c」は、.bashrcや.profile、その他の通常のソースファイルを新しいインタラクティブシェルターミナルに提供していないようです。 simple_user .bashrcファイルに次の行を追加することで確認しました。

export TEST="Hello"

次に、「simple_user_service」initスクリプトで:

#!/bin/bash
### BEGIN INIT INFO
# Provides:             test_script
# X-Interactive:        true
# Short-Description:    Test script
### END INIT INFO

echo $TEST

スクリプトを実行しても何も出力されませんが、次のコマンドを実行すると:

su simple_user
echo $TEST
> Hello

TEST変数が設定され、正しく出力されます。

だから私は疑問に思っていました:「exec su simple_user -c」コマンドは、simple_userプロファイル/ bashrcファイルをソースしますか?もしそうなら、どれを知る方法はありますか?

ご協力ありがとうございました!

[編集-2時間後]

受け取った回答のおかげで、「man bash」の指示をより正確に理解しました。私はこれを見つけました:

   When bash is started non-interactively, to run a Shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it  appears  there,  and
   uses the expanded value as the name of a file to read and execute.  Bash behaves as if the following command were executed:
          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
   but the value of the PATH variable is not used to search for the file name.

完全なインタラクティブロジックをロードせずに「su simple_user -c」を使用するたびに特定のコマンドを実行するファイルにBASH_ENVを設定できるため、非常に興味深いです。

したがって、su simple_user -cを実行する前に、次のことを簡単に行うことができます。

export BASH_ENV=~/.bash_script

そして、以下のようにsimple_user .bash_scriptファイルに設定します:

export TEST="Hello"

次に、「simple_user_service」スクリプトを実行すると、「Hello」が正しく出力されます。

特定のスクリプトを実行するためにすべての「rvm」環境(Ruby)をロードするためにこれが必要だったので、私にとって本当に役に立ちました。

もっと知りたいですか?

なぜこのすべてのトラブル?

Ruby god: http://godrb.com/ をインストールしたため、この特定のスクリプト(遅延ジョブ1)を監視します。

そして、私は「rvm」を使ってさまざまなルビーを管理しています。

また、必要に応じて、スクリプトはexec su application_user -c "/bin/bash application_script"を実行して自動的に特権を削除します

神はルート権限で実行する必要があり、rvmは.bashrc/.profileファイルにのみロードされるため、スクリプトでrvm環境を適切にロードする方法が必要でした。スクリプトにrvm loadコマンドを追加するだけでも、スクリプトは環境に依存することになり、受け入れられませんでした。

そのため、特権を削除する前にスクリプトにこれを追加しました。

if [ -e "config/BASH_ENV" ]; then
  export BASH_ENV=$(cat config/BASH_ENV)
fi

そのおかげで、config/BASH_ENVファイルで設定したファイルにrvmをロードできます。たとえば、次のようになります。

# In config/BASH_ENV file of your Rails app:
export BASH_ENV="~/.bash_script"

# In /home/simple_user/.bash_script 
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function

その後、私のスクリプトと神は期待どおりに動作します。

読者が本当の質問に集中できるように、答えを得る前にそれらすべてを説明しませんでした。

しかし、私は良い答えを得て、そのおかげで良い解決策を見つけたので、他の人に役立つようにこの編集を書きました。

再度、感謝します!

7
Kulgar

あなたがするとき:

su some_user -c 'some_command'    

some_commandは次のように実行されます。

bash -c 'some_command'

bashsome_user/etc/passwdのシェルで定義されていると仮定します。

bash -c 'some_command'を実行すると、基本的にbashの-​​非対話型(そしてもちろん非ログイン)セッションが生成されます。非対話型モードではシェルからファイルが取得されないため、予想されるファイルの読み取りは行われません。

~/.profilebashのログインの対話型セッションで提供され、~/.bashrcbashの非ログインの対話型セッションで提供されることに注意してください。また、Ubuntuは~/.bashrcから~/.profileをソースすることに注意してください。

man bashINVOCATIONセクションを確認して、より多くのアイデアを得てください。

9
heemayl