web-dev-qa-db-ja.com

`Sudo`はどのようにして実行可能ファイルのパスを検索しますか?

Ubuntu 10.10でroot権限を必要とするgemでrubygems(1.3.7)を使用しています。セットアップをrubygems1.3.6をインストールしたubuntu9.10と比較すると、gem environmentに次の違いがあります。

1.3.7/10.10 - EXECUTABLE DIRECTORY: /var/lib/gems/1.8/bin

1.3.6/09.10 - EXECUTABLE DIRECTORY: /usr/bin

Sudoを使用するかどうかに関係なく、出力は同じです。これを修正するために(そもそもなぜ違うのかわかりません)、path変数を変更しようとしました。

私の質問は、Sudoはどこで実行可能ファイルを探すのですか? (Sudoを使用して)gemをインストールすると、実行可能ファイルは明らかに/varパスに配置されます。このパスを~/.profileファイルと/etc/environmentファイルに追加しましたが、実行可能ファイルを実行するためにSudoを取得できません。

私が実行した場合:

  • $ gemnameツールを正しく実行します。
  • $ Sudo gemnameそれは単にcommand not foundを教えてくれます。
  • $ Sudo echo $PATH itdoesは正しいパスを示します。
  • $ Sudo -i gemname正しく実行されます。
  • $ Sudo sudo -Vは、PATHが保持されていることを示します。

Sudo~/.profileおよび/または/etc/environmentを尊重しますか?もしそうなら、ディレクトリが$PATH環境変数に表示されているのに、なぜ実行可能ファイルが見つからないのですか?

Sudoのドキュメントを読みました。また、stackoverflowとserverfaultに関する多数のトピックを検索して調べました(たとえば、 sudoでPATH環境変数をオーバーライドする方法は? ですが、例は、$PATHに正しいパスが含まれていることを示しています)が、実際にはSudoを介してgemを実行する方法を示していません。

7
Kamiel Wanrooij

3番目のコマンドでは、Sudoが表示する前にシェルが_$PATH_を展開するため、出力はSudoが表示するPATHではなく、シェルのパスであることに注意してください。必要なのは_Sudo echo \$PATH_または_Sudo sh -c 'echo $PATH'_のようなものです。

それ以外にも、Sudo(8) manページのSECURITYNOTESセクションを見てください。 UbuntuはSECURE_PATHビルドオプションを使用してSudoをビルドすると思います。 _Sudo sudo -V_の出力で「ユーザーの$ PATHをオーバーライドする値」の行を探します。

_Sudo -i_は初期ログインをシミュレートするため、_.profile_のようなファイルを読み取ります(ただし、読み取るファイルはルートのシェルによって異なります)。 _-i_がないと、保存された環境変数が呼び出し元の環境から継承され、前述のPATHサニテーションが使用されます。

そもそもなぜパスが変わったのかというと、開発者側の意図的な選択だったのではないかと思います。 bugs.debian.org に関する詳細な議論を参照してください。

10
justarobert

パーツごとに行きましょう:

  • gemnameそれは私のツールを正しく実行します。

それで大丈夫です :)

  • Sudo gemnameは、コマンドが見つからないことを通知するだけです。

gemnameはあなたの$PATHにありません

  • Sudo echo $ PATH正しいパスを表示します。

これはすばらしいことです。変数の展開は、bashがプログラムを実行する前に行われます。したがって、これを実行すると、ユーザー$PATHbefore Sudoを呼び出すように展開されるため、Sudoに渡される行は次のようになります。

$ Sudo echo "/usr/bin:/bin:"
  • Sudo -igemnameは正しく実行されます。

Sudo -iはログインシェルとして実行され、.profileおよび/または.loginを尊重します。 manページのように:

また、環境を初期化し、DISPLAYとTERMを変更せずに、HOME、MAIL、Shell、USER、LOGNAME、PATH、およびLinuxおよびAIXシステムの/ etc/environmentの内容を設定します。他のすべての環境変数は削除されます。

3
coredump