su コマンド:su と su - の違い、sudo su と sudo -i までアカウントを切り替える方法
Linux で今のアカウントからログアウトせずに別のアカウントに切り替えてコマンドを実行するときは、su コマンドを使います。AlmaLinux 9 サーバーの root アカウントから、ログインできないシステムアカウント daemon へ su を実行して比べたところ、ハイフン1つで作業フォルダーと PATH が変わり、シェルを指定しないとコマンドが実行されませんでした。
以下の出力は AlmaLinux 9.8 サーバー(root アカウント)と Debian 12 サーバー(一般アカウント)で実行した結果です。パスワードを尋ねる画面と sudo は運用中のサーバーでは実行せず公式マニュアルに基づいてまとめ、PATH の値の一部とシミュレーターの util-linux パッチバージョン番号は例の値に置き換えました。
1️⃣ su コマンドの使い方
基本の形は [su アカウント名] で、アカウント名を省くと root に切り替わります。切り替えたシェルで exit と入力するとそのシェルが終わり、su を実行した元のアカウントのシェルに戻ります。
一般アカウントから実行すると、Password: の行に切り替え先アカウントのパスワードを入力します(PAM の初期設定に基づく)。このサーバーの /etc/pam.d/su は実行した人が root なら認証を省く設定になっていて、root アカウントから daemon に切り替えたときはパスワードを尋ねませんでした。
su --help
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).ヘルプにあるとおり、ハイフン [-] は [-l] と同じログインオプションで、アカウント名の後ろに書いた引数は切り替え先アカウントのシェルに渡されます。AlmaLinux 9 サーバーの su は util-linux 2.37 パッケージ、Debian 12 サーバーの su は 2.38 パッケージに入っていました。
su --versionsu from util-linux 2.38.1切り替えたいアカウントがシェルを開けるかどうかは、getent passwd でアカウント行の最後の欄を見ると分かります。
getent passwd daemondaemon:x:2:2:daemon:/sbin:/sbin/nologindaemon のシェルは /sbin/nologin でした。ログイン用シェルの代わりに nologin が入っているアカウントは、su で切り替えてもシェルが開きません。
2️⃣ su と su - の違い
ハイフン(-)を付けると、su は切り替え先アカウントでログインしたのと同じシェルを開きます。/tmp フォルダーで同じコマンドをハイフンなしで1回、ハイフンを付けて1回実行しました。
su -s /bin/sh -c pwd daemon/tmpsu - -s /bin/sh -c pwd daemon/usr/sbinハイフンがないと作業フォルダーは /tmp のままで、[su -] は daemon のホームフォルダー /sbin に移りました。このサーバーの /sbin は /usr/sbin へのリンクなので、pwd には /usr/sbin と表示されました。
環境変数は、env の出力から HOME、USER、SHELL、PATH、LOGNAME の5行だけを選んで比べました。
su -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binsu - -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbinHOME、USER、LOGNAME はどちらの場合も daemon の値に変わりました。PATH はハイフンがないと su を実行した root の値がそのまま残り、[su -] ではログイン設定に従って新しく決まりました。
公式マニュアルによると、ハイフンなしの su は HOME と SHELL だけを変え、切り替え先が root でないときだけ USER と LOGNAME も変えます。そのため一般アカウントからハイフンなしで root に切り替えると、USER には元のアカウント名が残ります。
シェル名を表示する [$0] も違いました。
su -s /bin/sh -c 'echo $0' daemonshsu - -s /bin/sh -c 'echo $0' daemon-sh[su -] ではシェル名の前にハイフンが付き、-sh と表示されました。シェルは名前がハイフンで始まるとログインシェルとして動き、ログイン設定ファイルを読み込みます(公式マニュアルに基づく)。2つの形の違いは次のとおりです。
| 比較 | su | su - |
|---|---|---|
| 作業フォルダー | そのまま(/tmp) | 切り替え先アカウントのホームフォルダー(/usr/sbin) |
| HOME, USER, LOGNAME | daemon の値 | daemon の値 |
| PATH | su を実行した root の値 | ログイン設定で新しく決まる |
| シェル名($0) | sh | -sh(ログインシェル) |
| その他の環境変数 | そのまま残る | TERM など一部だけ残して消える(公式マニュアルに基づく) |
公式マニュアルは、環境が混ざらないようにログインオプションを常に付け、ハイフンの代わりに [--login] と書くことを勧めています。ハイフンなしの su は今のフォルダーと PATH が残るため、別のアカウントの設定でコマンドを確かめたい場合には [su -] と違う結果になることがあります。
3️⃣ su -c と su -s オプション
シェルを開かずにコマンドを1つだけ別のアカウントで実行するときは、-c の後ろにコマンドを書きます。nologin のアカウントに [su -c] で id を実行すると、コマンドの代わりに拒否の文言が表示されました。
su -c id daemonThis account is currently not available.-c で渡したコマンドもアカウントのシェルが受け取って実行するため、シェルが nologin だとコマンドまでたどり着きません。このときは -s で実行するシェルを指定します。
su -s /bin/sh -c id daemonuid=2(daemon) gid=2(daemon) groups=2(daemon)/bin/sh を指定すると、id が daemon の UID 2 で実行されました。サービスアカウントでファイルの権限やコマンドの結果を確かめるときにこの形を使います。
切り替え先アカウントのシェルが nologin のように /etc/shells にない制限付きシェルなら、-s でシェルを変えられるのは root だけです。公式マニュアルによると、root 以外のユーザーが指定した -s と SHELL 変数はこのとき無視されます。
-c の後ろのコマンドに空白があるときは、引用符で囲んでひとまとまりで渡します。su は実行したコマンドの終了コードをそのまま返し、コマンドを実行できなければ 126、見つからなければ 127 を返します(公式マニュアルに基づく)。
📌 主なオプション: この記事で実行した結果
| オプション | 作業 | この記事で確認した結果 | |
|---|---|---|---|
| - | 切り替え先アカウントでログインしたのと同じシェルを開き、そのアカウントのホームフォルダーに移る | /tmp でハイフンなしだと pwd は /tmp、付けると /usr/sbin で、echo $0 は -sh | |
| -c コマンド | シェルを開かずにコマンドを1つ、切り替え先アカウントのシェルで実行 | nologin のアカウント daemon に su -c id daemon を実行すると [This account is currently not available.] | |
| -s シェル | アカウントに書かれたシェルの代わりに指定したシェルで実行、制限付きシェルのアカウントは root のみ | su -s /bin/sh -c id daemon で uid=2(daemon) gid=2(daemon) groups=2(daemon) | |
| --help | 使い方とオプション一覧を表示 | Usage 行と -m、-w、-g、-G、-l、-c、-f、-s、-P、-h、-V のオプション一覧 | |
| --version | バージョン情報を出力 | Debian 12 サーバーで su from util-linux 2.38.1 |
📎 その他のオプション: 公式マニュアルより
| オプション | 作業 | |
|---|---|---|
| -l | ハイフン(-)と同じログインオプション、長い名前は --login | |
| -m | 環境変数をそのままにし、HOME、SHELL、USER、LOGNAME も変えない、ログインオプションと一緒に使うと無視(-p と同じ) | |
| -w リスト | ログインオプションで環境を消すときにカンマで書いた変数を残す、HOME、SHELL、USER、LOGNAME、PATH は新しく決まる | |
| -g グループ | プライマリグループを指定、root のみ | |
| -G グループ | 補助グループを指定、root のみ、-g がなければ最初の補助グループがプライマリグループ | |
| -f | シェルに -f を渡す、csh や tcsh で使うオプション | |
| -P | 新しい疑似端末を作り、元のセッションと端末を共有しない | |
| --session-command コマンド | -c と同じだが新しいセッションを作らない、マニュアルは勧めていない |
🔲 su コマンドシミュレーター
下のシミュレーターは一般アカウント user1 から始まり、su と [su -]、sudo を入力して exit で戻る流れを実際に確かめられます。アカウントとパスワードは例の値です。
4️⃣ sudo su と sudo -i の違い
sudo su は、sudo で su を root 権限で実行する形です。su を root が実行するため root のパスワードは尋ねられず、その前に sudo が実行した人のパスワードを尋ねます(公式ドキュメントに基づく)。
sudo を実行できるアカウントは /etc/sudoers の設定で決まります。許可されていないアカウントが sudo を実行すると、[user1 is not in the sudoers file.] で拒否されます(プログラム内の文言に基づく)。
root シェルを開くコマンドごとに、尋ねられるパスワードと作業フォルダーは次のとおりです。この章のコマンドは運用中のサーバーでは実行せず、su(1) と sudo(8) のマニュアルに基づいてまとめました。
| コマンド | 尋ねられるパスワード | 実行されるシェル | 作業フォルダー |
|---|---|---|---|
| su | root | root シェル | そのまま |
| su - | root | root ログインシェル | /root |
| sudo su | 実行したアカウント | root シェル | そのまま |
| sudo su - | 実行したアカウント | root ログインシェル | /root |
| sudo -i | 実行したアカウント | root ログインシェル | /root |
| sudo -s | 実行したアカウント | SHELL 変数のシェル(root 権限) | そのまま |
[sudo -i] と [sudo su -] はどちらも root ログインシェルになります。[sudo -i] は sudo が root のシェルを直接ログインシェルとして実行し、[sudo su -] はその間で su をもう一度通ります。
[sudo -s] は SHELL 変数のシェルを root 権限で実行し、ホームフォルダーには移りません。sudo はパスワードを一度正しく入力すると、初期値で5分間は同じ端末で再び尋ねません(sudoers マニュアルに基づく)。
su と sudo の違いは、家の鍵を借りることと、管理室で名前を書いて出入りすることの違いと同じです。
5️⃣ su コマンドのエラー
ログインできないアカウントに切り替えると、シェルの代わりに nologin が実行されて [This account is currently not available.] と表示されます。root で [su daemon] を実行すると、この1行だけが表示されて終了コードは 1 でした。
su daemonThis account is currently not available.この文言はアカウント行の最後の欄に書かれた nologin プログラムが表示するもので、サーバーの /usr/sbin/nologin の中で同じ文言を確認しました。root なら -s でシェルを指定して、そのアカウントでコマンドを実行できます。
パスワードが合わないと [su: Authentication failure] と表示されます。この文字は PAM ライブラリーが認証失敗のときに返す文言です。公式マニュアルによると、su がコマンドを実行する前に失敗すると終了コードは 1 です。
自分のアカウントのパスワードを正しく入れたのに su が拒否するなら、切り替え先アカウントのパスワードを入れる場面かどうかをまず確かめます。sudo は実行した人のパスワードを尋ね、su は切り替え先アカウントのパスワードを尋ねるからです。
存在しないアカウント名を書くと [su: user user9 does not exist or the user entry does not contain all the required fields] と表示されます(プログラム内の文言に基づく)。エラーごとの原因と確かめることは次のとおりです。
| 出力 | 原因 | 確かめること |
|---|---|---|
| This account is currently not available. | 切り替え先アカウントのシェルが nologin | getent passwd のアカウント行の最後の欄・root は -s でシェルを指定 |
| su: Authentication failure | パスワードが合わない | 切り替え先アカウントのパスワードか(sudo は自分のパスワード) |
| su: user user9 does not exist … | その名前のアカウントがない | getent passwd アカウント名 |
| user1 is not in the sudoers file. | sudo を許可していないアカウント | sudoers の設定と wheel グループ |
🔢 FAQ & おすすめコンテンツ
ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。