web-dev-qa-db-ja.com

`bash -c`で環境変数が異なるのはなぜですか

次の理由、つまり$PATHから直接bash -cをエコーする方法:

docker exec -i -t my_container bash -c "echo $PATH"

$PATHに対して次の値とは異なる値を返します。つまり、インタラクティブなbashセッションを開始して$PATH?をエコーし​​ます。

docker exec -i -t my_container bash 
root@21e6d898c3c2:/# echo $PATH

この質問にいくつかのコンテキストを与えるために、docker execを使用してコンテナーでコマンドを実行します。このコマンドは、対話型のbashセッションを開始する場合はパス上にありますが、単にコマンド。

この場合、コマンドはPATHと同様にbashインタラクティブセッションで設定される他の環境変数に依存しますが、コマンドを実行した場合は実行可能ファイルのフルパスを使用することは回避策ではありません。まっすぐ。

12

-cが指定されている場合、bashinteractiveまたはloginシェルとして実行されていないため、同じ起動スクリプトを読みません。 /etc/profile~/.bash_profile~/.bash_login、または~/.profileで設定されたものはすべてスキップされます。

また、bash manページで説明されているように:

Bashは、リモートシェルデーモン(通常はrshd)またはセキュアシェルデーモンsshdによって実行されるときのように、標準入力がネットワーク接続に接続された状態で実行されているかどうかを判断しようとします。この方法で実行されているとbashが判断した場合、これらのファイルが存在し、読み取り可能であれば、~/.bashrcおよび~/.bashrcからコマンドを読み取って実行します。

そのため、ネットワーク経由で接続していると思わない場合は、.bashrcファイルも読み取れない可能性があり、前の手順でスキップされなかったものはすべてスキップされます。

解決

この問題を回避するには、PATHを適切なものに設定するスクリプトを作成し、コマンドを実行します。既存の.profileまたはその他のファイルを使用する場合は、スクリプトで ソースを追加する を使用できます。

5
chicks

最初の例では:

docker exec -i -t my_container bash -c "echo $PATH"

これにより、Dockerクライアントのシェルを使用して、コンテナーの外部で$PATH変数を評価し、コンテナー内で実行するコマンドとして展開された値を渡します。上記の値をdocker外のコマンドラインで実行中のecho $PATHと比較して、それらが同じであることを確認できます。

2番目の例では:

docker exec -i -t my_container bash 
root@21e6d898c3c2:/# echo $PATH

これにより、コンテナ内の$PATH変数が評価されます。

最初の例をエスケープするか、一重引用符で囲んで、ワークステーションのbashシェルが展開しないようにして、コンテナー内で評価されるようにすることができます。次のいずれかが機能します。

docker exec -i -t my_container bash -c "echo \$PATH"
docker exec -i -t my_container bash -c 'echo $PATH'
6
BMitch

bash-lオプションを試してください。ログインシェルで実行され、/etc/profileが読み込まれます。

docker exec -i -t my_container bash -lc "echo $PATH"
2
Max Ivak