web-dev-qa-db-ja.com

実行可能ファイルはSudoなしで実行されますが、sudoなしでは実行されます

システムの/opt/lamppにxamppをインストールしました。その後、次を使用してphpの場所をパス変数に追加しました

export PATH=$PATH:/opt/lampp/bin

したがって、ターミナルを使用してphp -vを実行すると、予期した出力が得られます。

PHP 5.6.8 (cli) (built: Apr 20 2015 18:37:47) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

しかし、Sudo php -vを実行すると、次のようになります。

Sudo: php: command not found

これが起こる理由はわかりません。パス変数に追加するときに何か間違ったことをしていますか?

編集:

この質問は 'Sudo'で実行した場合の環境変数 の複製ではありません。なぜなら、その質問でzetahは任意の変数をpythonコマンドに渡す方法を尋ねたからです。 pythonを使用してSudoを実行できますが、phpを使用してSudoを実行できません。

この回答 に続いて、次のコマンドを使用してSudoにPATHを追加しました。

Sudo PATH=$PATH:/opt/lampp/bin php -v

しかし、私は以前のように出力を得ています:

Sudo: php: command not found

この回答 に従って、-ESudoに追加しましたが、同じ結果が得られます。

$ Sudo -E php -v
Sudo: php: command not found
2

SudoがPATHを使用しない理由

SudoがPATH変数を無視する理由は、それが独自の_secure_path_を持ち、それを使用することはかなり決まっているからです。

_Sudo cat /etc/sudoers_または単に_Sudo grep secure /etc/sudoers_の場合、このパスがシステム上にあることがわかります。私はこの行を持っています:

_Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
_

Sudoの_secure_path_の目的は、Sudo特権を持つユーザーが、パスが変更された後にルートとして(偶然に)危険なコードを実行する可能性を低くすることです。ローカルディレクトリを含めるため。

_secure_path_を変更して_/etc/sudoers_を使用することでSudoを回避することは可能ですが、その行をコメントアウトすることは悪い考えです。さまざまな望ましい方法で簡単に回避できます。

Sudoを取得してPATHを使用する

_secure_path_をオーバーライドし、Sudoが現在定義されているPATHを使用するようにするには、 as muru commented を使用します。

_Sudo env PATH="$PATH" command_

_-E_フラグまたは単に変数を割り当てることは機能しません(少なくともUbuntuでは)。

_$ mkdir junk                            # create a test directory to add to PATH
$ echo "echo foo" > junk/useless        # create a harmless program
$ chmod u+x junk/useless                # make it executable
$ PATH="$PATH":~/junk                   # add directory to PATH
_

PATHに追加するときは、絶対パスを使用します(シェルは変数を割り当てる前に_~_を展開します)。 PATHは既にエクスポートされており、その値を変更すると子プロセスも変更を継承するため、exportを使用する必要はありません(そうすることは役に立ちません)。

_$ useless
foo
$ Sudo useless
Sudo: useless: command not found
$ Sudo -E useless
Sudo: useless: command not found
_

多くの場合、これが機能すると期待されています... _man Sudo_ 言います:

_-E, --preserve-env
            Indicates to the security policy that the user wishes to
            preserve their existing environment variables.
_

しかし、それは機能しません。 _-E_フラグは_secure_path_に影響を与えません。 これはバグである可能性があります

_$ Sudo PATH="$PATH" useless
Sudo: useless: command not found
_

これは、 _/etc/sudoers_ で設定されたセキュリティポリシーに従って設定されたSudoの独自の環境には影響しません。これには、Ubuntuのデフォルトとして_env_reset_および_secure_path_が含まれ、最小限の環境がロードされ、PATHが_secure_path_にあるものに設定されます。

Sudoが独自のパスディレクトリのいずれかでuselessというコマンドを見つけて実行できる場合、_PATH=$PATH_をその環境に渡します ここに示すように 。ただし、それ自体は指定されたPATHの値を使用しません。解決策は以下を実行することです:

_$ Sudo env PATH="$PATH" useless
foo
_

この回避策では、envコマンドを使用してPATHを設定します。 Sudoとは異なり、envは指定された変数を使用して環境を設定し、コマンド引数を探して、変更された環境でコマンドを実行します。 info (coreutils) env invocation のように:

PATHへの変更は、commandを検索する前に有効になります。

PATHを設定する

PATH変数を変更してディレクトリ_/opt/lampp/bin_を含めるときに、次のコマンドを使用しました。

_export PATH=$PATH:/opt/lampp/bin
_

これは、現在のシェルと、このシェルから呼び出されるシェルなど、現在のシェルのすべての子プロセスに対して有効です。このシェルを終了し、そのすべての子が終了すると、変更されたPATH変数は完全に忘れられ、新しいシェルを開くと、_/opt/lampp/bin_を含まない古いPATH変数が見つかります。そのため、完全なコマンド muruによる提案

_Sudo env PATH="$PATH:/opt/lampp/bin" php -v
_

_/opt/lampp/bin_を既に追加したシェルをまだ使用していない場合は必要でした。

パスを永続的に変更するには、ユーザー環境を変更するか、シェルの起動時にシェルによって読み取られる構成ファイルを編集する必要があります。 _~/.profile_で環境変数を割り当てる行を追加できます。例:

_PATH="$PATH:/opt/lampp/bin"
_

その後、ログアウトしてから(または_source ~/.profile_を実行してすぐに効果を確認した後)、いつでも実行できます

_php -v
_

または

_Sudo env PATH="$PATH" php -v
_

最初にPATHを調整せずに。

面倒ではない代替

より便利な回避策は、_secure_path_およびデフォルトのPATHにある場所で実行可能ファイルへのシンボリックリンクを作成することです。次に例を示します。

_Sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
_

そうすれば、Sudoを指定してコマンドを呼び出すときに特別なことをする必要がなくなり、PATHを恒久的または一時的に調整するための手順を実行する必要がなくなります。

インストールしているプログラムの名前が、システムプロセスが呼び出そうとする別のプログラムの名前と同じ場合、シンボリックリンクに別の名前を付けます、これらのプロセスの混乱を避けるため。 typeコマンドを使用して、使用する名前が他のコマンドの名前ではないことを確認できます。

_$ type php
bash: type: php: not found
_

そのため、このシステムでは、現時点で何か問題が発生することを恐れずに、phpコマンドを作成できます。将来phpコマンドを提供する他のプログラムをインストールする場合、構成を再考する必要があるかもしれません。

また、コマンドのエイリアスを作成し、それを_~/.bashrc_に追加することもできます。次に例を示します。

_alias Sudo-php='Sudo env PATH="$PATH:/opt/lampp/bin/php"'
_

(_source .bashrc_を実行した後、または新しいシェルを開いた後)実行できます

_Sudo-php
_

このプログラムをルートとして実行するために_Sudo php_の代わりに、Sudoはその場所を知らないと主張しません。

このエイリアスは対話型シェルでのみ使用できるため、他のプログラムを混乱させることはありません。

もちろん、Sudoだけのエイリアスを作成して、常に_alias Sudo='Sudo env PATH="$PATH"'_を使用してPATHを使用することもできますが、システムの安全性が低下するため、これは悪い考えです。

3
Zanna