3つの関数を実行するスクリプトがあります:A && B && C
。
関数B
はスーパーユーザーとして実行する必要がありますが、A
とC
は必要ありません。
私はいくつかの解決策を持っていますが、どちらも満足していません:
スクリプト全体をsudoする:Sudo 'A && B && C'
A
とC
が必要ない場合にスーパーユーザーとして実行するのは悪い考えのようです
スクリプトをインタラクティブにします:A && Sudo B && C
パスワードを入力する必要があるかもしれませんが、各関数には時間がかかる可能性があるため、スクリプトを非対話型にして、スクリプトが私を待機しないようにしたいと思います。まあ、それがそもそもそれがスクリプトであるためです。そのため、実行を監視する必要はありません。
愚かな解決策:Sudo : && A && Sudo -n B && C
最初に何もしないSudo
を最初に実行するのはばかげているように思われます。また、Aが$Sudo_timeout
を超えることはないので、指を交差させなければなりません。
架空の解決策(存在することを教えてください):
Sudo --store-cred 'A && Sudo --use-cred-from-parent-Sudo B && C'
最初にパスワードの入力を求め、必要な場合にのみその資格情報を使用します。
このすべてについてあなたの意見は何ですか?私はそれがかなり一般的な問題だと思うので、その問題の解決策がないことに非常に驚きます(make all && Sudo make install
はどうですか)
あなたができる最善のことは、Sudo
でスクリプトを起動してから、su user
またはSudo -u user
で明示的に通常のユーザーとして実行するプロセスを起動することです。
#!/usr/bin/env bash
## Detect the user who launched the script
usr=$(env | grep Sudo_USER | cut -d= -f 2)
## Exit if the script was not launched by root or through Sudo
if [ -z $usr ] && [ $USER = "root" ]
then
echo "The script needs to run as root" && exit 1
fi
## Run the job(s) that don't need root
Sudo -u $usr commandA
## Run the job that needs to be run as root
commandB
スクリプトを/etc/sudoers
ファイルにNOPASSWD
属性を付けて追加すると、パスワードを要求せずに実行できるようになります。これを特定のユーザー(またはユーザーのセット)に結び付けるか、システム上のすべてのユーザーがSudo
を使用して実行できるようにすることができます。
/usr/local/bin/bossy
というスクリプトのサンプル行は、次のようになります。
ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy
そして、あなたはこのようなものを使うでしょう
A && Sudo bossy && C
この例では、PATH
に/usr/local/bin
が含まれていると想定しました。そうでない場合は、スクリプトへのフルパスを使用してください。つまり、Sudo /usr/local/bin/bossy
Sudo
の!requiretty
オプションとNOPASSWD
オプションを使用することもできます。ただし、これによりセキュリティが低下することに注意してください。
sudoを事前承認しますか?(後で実行できるようにするため) への私の回答に基づいて、2つのスクリプトを記述します。
ABC_script
:
#!/bin/sh
Sudo -b ./B_script
A && > A_is_done
while [ ! -f B_is_done ]
do
sleep 60
done
rm -f B_is_done
C
B_script
:
#!/bin/sh
while [ ! -f A_is_done ]
do
sleep 60
done
rm -f A_is_done
B && > B_is_done
./ABC_script
を実行します。
Sudo -b ./B_script
を実行します。これはパスワードを要求します(即時ABC_script
の実行後)。正しいパスワードが入力されていると仮定すると、B_script
が bルートとしてackground(-b
が指定されたため)。これはSudo sh -c "./B_script &"
と同等のようです。B_script
は、ABC_script
と並行して非同期で実行を開始します。 B_script
は、A_is_done
というファイルの存在をテストし、表示されるまでループします。ABC_script
はA
を実行します。 A
が正常に終了すると、スクリプトはA_is_done
というファイルを作成します。ABC_script
はB_is_done
というファイルの存在をテストし、表示されるまでループします。B_script
はA_is_done
の存在を検出し、ループから抜け出します。 A_is_done
ファイルを削除し、B
を実行します。 B_script
はrootとして実行されているため、B
はrootとして実行されることに注意してください。 B
が正常に終了すると、スクリプトはB_is_done
というファイルを作成して終了します。ABC_script
はB_is_done
の存在を検出し、ループから抜け出します。 B_is_done
ファイルを削除します。 B_script
はrootとして実行されているため、B_is_done
はrootが所有しているため、rm -f
を使用して確認のリクエストを取得しないようにしてください。 ABC_script
は次にC
を実行して終了します。さらなる洗練のためのメモ:
ABC_script
は、おそらくB_script
ではなく、絶対パスで./
を実行する必要があります。A_is_done
およびB_is_done
ではなく、ABC_script
はランダムで一意のファイル名を生成する必要があります。待機しているプログラムが終了したが失敗した場合に通知を受け取るには、スピン待機しているスクリプトを準備する必要があります。 (現在、A
が失敗した場合、両方のスクリプトが無限の待機ループに入るだけです。)これは、変更するだけの簡単なことです。
A && > A_is_done
に
A; echo $? > A_is_done
次に、スピンウェイトを変更してX_is_done
ファイルを読み取り、0が含まれている場合は続行し、それ以外の場合は終了します。