環境
OS X YosemiteとLinux(RedHat系)でのテスト。
OS Xでのrootユーザーの有効化についてはAppleのページで確認。
rootユーザーとしてログインして実行した時や、
suでrootとなった場合、
sudoでroot権限を持って実行する場合に
スクリプトやプログラムの中でrootかどうか判断したい、と言う状況での話です。
ユーザー名
USER名で判断用とするこんなスクリプト:
1 2 3 4 5 6 | |
これだと通常ユーザーだとnon-root user!と出て、
rootでログインして実行するとroot!と出ます。
ただし、suでrootになった場合、$USERの値は元のままなので
これだと失敗します。
$ su
# ./root_check.sh
non-root user!
一方、sudoで実行すると
一時的にユーザーごと全て変更されるので、
$USERもrootに変更されます。
$ sudo ./root_check.sh
root!
sudo echo $USERの様にコマンドを直接実行してしまうと
引数部分の変数が展開されてからsudoに渡される形になってしまうので
この場合は本のユーザー名が出てしまいます。
$ sudo echo $USER
user
また、sudo -sを使うと渡した引数を新たなシェルで実行する様な形になるのですが、
Macの場合、
$ sudo -s 'echo $USER'
root
とシングルクォートで囲って渡すと$USER部分をそのままの状態で
渡して、その後シェルを立ち上げてecho $USERを実行する形になり、
結果的にrootが出ます。
コマンド部分をクォートしないか、ダブルクォートで囲うとまず
$USERを解釈してからsudoに渡すのでuserが出ます。
$ sudo -s "echo $USER"
user
ここでLinuxでやってみると、クォートしない場合は同じ結果ですが、 クォートすると
$ sudo -s 'echo $USER'
みたいなエラーが出てしまいます。 ダブルクォートでも
$ sudo -s "echo $USER"
/bin/bash: echo user: command not found
sudoの仕様が少し違う様です。
これ以外に$LOGNAMEという環境変数がありますが、
こちらの場合だと、suした時はrootになり、
sudoだと元のユーザー名になります。
ので、これらを使ってやる方法はちょっと上手く行きません。
UID
そこで、$UIDを使ってみます。
1 2 3 4 5 6 | |
これだとsuした時も$UIDは0になり、rootとそれ以外のユーザーを
区別することが出来ます。
普通はしないですが、rootのユーザー名を変更した場合にもこれだと大丈夫。
Pythonなら
1 2 3 4 5 6 | |
ついでにPythonでのユーザー名等の取り方等一覧。
1 2 3 4 5 6 7 8 9 | |
$ ./user_check.py # Normal user
501
user
user
user
user
$ sudo ./user_check.py
Password:
0
root
user
root
root
$ su
Password:
$ ./user_check.py
0
root
user
user
user
EUID
UNIXには$UIDに加えて$EUIDという
実効UIDがあります。
実効UID (effective UID)
実効UID (euid) と実効GID (egid) はファイル作成とファイルアクセスに影響する。ファイル作成時、カーネルはそのファイルの所有者を作成しているプロセスの実効UIDと実効GIDで設定する。ファイルアクセス時、カーネルはプロセスの実効UIDと実効GIDでアクセス権の有無を判断する。
と、Wikipediaにあります。
ただ、上のPythonスクリプトで
print os.geteuid()
を加えて実行してみても全てgetuidと同じ結果になりました。
ここにEUIDについて色々試したものが載ってますが(ちなみにリンク先ではCでのやり方が書いてあります)、 この通りにやっても上手く再現出来ません。
この辺、自分が何か勘違いしてるのかちょっと理解不足。
