sudo 実行時にユーザーの PATH を引き継ぐ方法

How to keep your PATH when using sudo on Linux

* 本ページはプロモーションが含まれています

Linuxでsudoコマンドを使うと、通常ユーザーで設定したPATHが反映されず「command not found」になることがあります。
特に、Linuxbrew(Homebrew)内のコマンドをsudo付きで実行しようとした際に、コマンドが見つからないことがよくあります。
この記事では、sudoでユーザーのPATH環境変数を引き継ぐ方法について解説します。

なぜsudoでPATHが変わるのか 

sudoはセキュリティ上の理由から、デフォルトで環境変数をリセットします。

多くのディストリビューションでは、/etc/sudoerssecure_pathが設定されており、sudo実行時はこの固定されたPATHが使われます。

# 通常ユーザーのPATH
$ echo $PATH
/home/user/.local/bin:/usr/local/bin:/usr/bin:/bin

# sudo実行時のPATH(リセットされている)
$ sudo sh -c 'echo $PATH'
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ユーザー独自のディレクトリ(~/.local/binなど)がsudo時には含まれないため、そこにインストールしたコマンドが見つからなくなります。

方法1: 一時的にPATHを引き継ぐ 

1回だけPATHを渡したい場合は、コマンド実行時にオプションを付けます。[1]

–preserve-env オプションを使う 

sudo --preserve-env=PATH your-command

特定の環境変数だけを指定して引き継げます。

env コマンドを使う 

sudo env PATH="$PATH" your-command

現在のPATHをそのまま渡して実行できます。

使用例 

# ~/.local/bin にインストールした mycli を root で実行
sudo --preserve-env=PATH mycli --config /etc/myapp/config.yaml

# または
sudo env PATH="$PATH" mycli --config /etc/myapp/config.yaml

方法2: sudoersでPATHを恒久的に引き継ぐ 

毎回オプションを付けるのが面倒な場合は、sudoersの設定を変更します。

手順 

  1. visudoを起動する(直接編集は危険なので必ずvisudoを使う)

    sudo visudo
  2. secure_pathの行をコメントアウトする

    # 変更前
    Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    
    # 変更後(先頭に # を付ける)
    #Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  3. PATHを引き継ぐ設定を追加する

    Defaults    env_keep += "PATH"
  4. 保存して終了(viなら:wq

設定後の確認 

$ sudo sh -c 'echo $PATH'
/home/user/.local/bin:/usr/local/bin:/usr/bin:/bin

ユーザーのPATHがそのまま引き継がれていれば成功です。

方法3: secure_pathに追加する 

既存のsecure_pathを活かしつつ、特定のディレクトリだけ追加する方法もあります。

sudo visudo
# 既存のパスに追加する形で編集
Defaults    secure_path="/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

この方法ならセキュリティ設定を維持しつつ、必要なパスだけ許可できます。

方法4: フルパスで実行する 

PATHに頼らず、コマンドを絶対パスで指定する方法です。

# コマンドの場所を確認
$ which mycli
/home/user/.local/bin/mycli

# フルパスで実行
$ sudo /home/user/.local/bin/mycli --version

設定変更が不要で、確実に動作します。

セキュリティ上の注意点 

secure_pathを無効化したりenv_keepでPATHを許可すると、悪意のあるスクリプトがPATHに紛れ込むリスクがあります。

方法メリットリスク
--preserve-env=PATH必要な時だけ使える毎回指定が必要
env_keep += "PATH"恒久的に便利PATH汚染のリスクあり
secure_pathに追加許可するパスを限定できる追加忘れが起きやすい
フルパス指定最も安全入力が長くなる

個人の開発マシンならenv_keepでも問題ありませんが、共用サーバーや本番環境ではsecure_pathへの追加かフルパス指定が推奨されます。

まとめの設定例 

個人開発環境向けの推奨設定をまとめます。

# /etc/sudoers(visudoで編集)
#Defaults    secure_path="..."   # コメントアウト
Defaults    env_keep += "PATH"

これで~/.local/binやHomebrewなど、ユーザー領域にインストールしたコマンドもsudoで実行できるようになります。


See also