サンプルスクリプトは次のようになります。
#!/bin/bash
Sudo su
ls /root
./test.sh
を通常のユーザーとして使用する場合、代わりにls
をスーパーユーザーとして実行して終了すると、rootに切り替わります。ログアウトすると、通常のユーザーとしてls /root
が実行されます。
メカニズムについて誰かに教えてもらえますか?
スクリプト内のコマンドは、個別に1つずつ実行されます。スクリプト内のすべてのコマンドの親としてのスクリプト自体は、別の独立したプロセスであり、suコマンドはそれをrootに変更することはできません。suコマンドは、root特権で新しいプロセスを作成します。
そのsuコマンドが完了すると、同じユーザーとして実行されている親プロセスが残りのスクリプトを実行します。
あなたがしたいことは、ラッパースクリプトを書くことです。特権コマンドは、メインスクリプトに含まれます(例:~/main.sh
#!/bin/sh
ls /root
ラッパースクリプトは、次のようにroot権限でメインスクリプトを呼び出します
#!/bin/sh
su -c ~/main.sh root
このプロセスを起動するには、ラッパーを実行します。ラッパーは、ユーザーをrootユーザーに切り替えた後にメインスクリプトを起動します。
このラッパー手法を使用して、スクリプトをそれ自体のラッパーに変えることができます。基本的に、ルートとして実行されているかどうかを確認し、実行されていない場合は、「su」を使用して自身を再起動します。
$ 0はスクリプトにそれ自体を参照させる便利な方法であり、whoamiコマンドは私たちが誰であるか(私たちはrootですか?)
したがって、組み込みラッパーを持つメインスクリプトは次のようになります。
#!/bin/sh
[ `whoami` = root ] || exec su -c $0 root
ls /root
Execの使用に注意してください。これは、「このプログラムを次のものに置き換える」ことを意味します。これにより、実行が事実上終了し、suによって起動された新しいプログラムがrootで開始され、上から実行されます。置換インスタンスは「ルート」であるため、||の右側は実行されません。
スクリプトで以下を使用します。
Sudo su <<HERE
ls /root
HERE
HEREブロック間のコードはrootとして実行されます。
追加の引数がない場合、su
はrootのログインシェルを実行します。これが、スクリプトの最初の行が実際に行うことです。終了すると、ログインシェルが閉じてsuが返され、スクリプトが実行を継続します。つまり、2行目です:ls /root
。単純にSudo ls /root
やりたいことを行う。
スーパーユーザーの有効なuserid (euid=EUID)
を使用してSudo su
新しいプロセスをフォークすると、同じ端末に関連付けられた別のプロセスID (pid=PID)
で新しいbashが実行されます(tname=TTY)
。
説明
ps -A | grep bash
を実行した後、出力として21460 pts/2 00:00:00 bash
があるとします。これで、./test.sh
を実行すると、Sudo su
とls /root
の両方のコマンドがPID 21460
にスプールされます。実行後、root
がアクティブユーザーとしてps -A | grep bash
を押したときに、PID say, 21570
で新しいbashが実行されていることがわかります。 root bash
を終了すると、新しく分岐したbashが終了してuser's bash
に戻り、プロンプトを解放する前にスプールされたコマンドls /root
を実行します。