sudo が一般ユーザーが見つけられるコマンドを見つけられないのはなぜですか?

sudo が一般ユーザーが見つけられるコマンドを見つけられないのはなぜですか?

しばらく前に NPM をインストールしていたのですが、sudo を使用してインストール シェル スクリプトを実行しようとすると、いくつかのコマンドが見つからないというエラーが発生することに気付きました。ただし、sudo を使用せずに同じスクリプトを実行しようとすると、すべて正常に動作しました。

私は Linux の初心者ですが、私の理解では、sudo の権限と可視性は通常のユーザーのスーパーセットです。

なぜそうなるのでしょうか?

答え1

私の理解では、sudo の権限と可視性は通常のユーザーのスーパーセットです。

権限は必要ですが、可視性は必ずしも必要ではありません。アプリケーションの可視性はPATH環境変数によって制御されます。

~$ printenv PATH
/home/vanadium/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/games

コマンドが入力されると、コマンド インタープリタはまず、それが内部コマンドであるかどうか、またはコマンドがディスク上の実行可能ファイルの名前に対応しているかどうかを確認します。次に、システムは、PATHコマンドに一致する名前の実行可能ファイルが見つかるまで、 にリストされているディレクトリを検索します。

例でわかるように、ユーザーは に追加のプライベート ディレクトリを持つことができ、そのディレクトリは、このユーザーがコマンドを発行したときにのみ検索されます。したがって、ユーザー アカウントには、ユーザー (つまり、コマンドを使用するときに想定されるロールである管理者)PATHとは異なるコマンドを使用できます。rootsudo

それでも、実行可能ファイルの権限は、最終的に誰がファイルを実行できるかを決定します。権限が許せば、実行可能ファイルは、プロンプトに/usr/bin/mountファイル名だけでなくフルパス名を指定することでいつでも実行できます。mountまた、root実行可能ビットが設定されている限り、所有者に対してのみであっても、いつでも実行できます。

答え2

ディレクトリ scripts 内のファイルを実行するとします。次のように実行します。

myscript.sh

スクリプトは正常に実行されます。しかし、sudo を実行した後、次のエラーが発生します。

sudo: myscript.sh: file not found

sudo が使用されるときは常に、ルート ユーザーのパスが使用されます。これを解決するには、次のようにコマンドを実行します。

sudo ./myscript.sh

答え3

シェル (bash など) は、通常のユーザー モードと sudo モードで異なる変数を使用します。次の手順に従ってこれを確認してください。

# Plain user
printenv > env1
# Using sudo
sudo printenv > env2
# Comparison
diff env1 env2
# Alternative comparison using the GUI tool meld
meld env1 env2

meldがインストールされていない場合は簡単にインストールできます。とても便利です。

sudo apt-get update
sudo apt-get install meld

プレーンな user / sudo の変数の内容が異なると、シェルの動作やスクリプトの機能に影響する可能性があります。

ファイルのアクセス権限も異なります。

答え4

実際のところ、それはそれよりも少し複雑です。 に存在する必要がある定義がいくつかあります/etc/sudoers

環境で何が起こるかを決定する制御フラグは、、、sudoおよびです。env_checkenv_keepenv_reset

sudoers のマニュアルページ「コマンド環境」セクションでは、これをわかりやすく説明しています。

$ man --pager="less -p '^\ *Command environment'" sudoers

すぐに使える Ubuntu 構成では、定義されているフラグがPATH呼び出されます(デフォルトで有効)。もデフォルトで有効になっているため、起動するsecure_pathユーザーの代わりに値が使用されます。PATHsudoenv_reset

$ man sudoers | egrep "^\ *secure_path" -A4 | sed 's/^ *//'

secure_path   If set, sudo will use this value in place of the user's PATH environment variable. This option can be used to reset the PATH to a known good
value that contains directories for system administrator commands such as /usr/sbin.

Users in the group specified by the exempt_group option are not affected by secure_path.  This option is not set by default.

(編集: 上記の最後の行は、exempt_groupではなく、 がデフォルトで有効になっていないことを指していますsecure_path)

これを (推奨) を使用して変更するか、表示することができますvisudo:

$ sudo grep secure_path /etc/sudoers
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

他の場合には、コマンドはbashに組み込まれており( などecho)、変数で参照できる実行可能ファイルではありませんPATH。これらの場合、何らかの値を または にパイプする必要がありますsudo bash -c他の方法

関連情報