web-dev-qa-db-ja.com

非インタラクティブスクリプトのsudo

3つの関数を実行するスクリプトがあります:A && B && C

関数Bはスーパーユーザーとして実行する必要がありますが、ACは必要ありません。

私はいくつかの解決策を持っていますが、どちらも満足していません:

  1. スクリプト全体をsudoする:Sudo 'A && B && C'

    ACが必要ない場合にスーパーユーザーとして実行するのは悪い考えのようです

  2. スクリプトをインタラクティブにします:A && Sudo B && C

    パスワードを入力する必要があるかもしれませんが、各関数には時間がかかる可能性があるため、スクリプトを非対話型にして、スクリプトが私を待機しないようにしたいと思います。まあ、それがそもそもそれがスクリプトであるためです。そのため、実行を監視する必要はありません。

  3. 愚かな解決策:Sudo : && A && Sudo -n B && C

    最初に何もしないSudoを最初に実行するのはばかげているように思われます。また、Aが$Sudo_timeoutを超えることはないので、指を交差させなければなりません。

  4. 架空の解決策(存在することを教えてください):

    Sudo --store-cred 'A && Sudo --use-cred-from-parent-Sudo B && C'

    最初にパスワードの入力を求め、必要な場合にのみその資格情報を使用します。

このすべてについてあなたの意見は何ですか?私はそれがかなり一般的な問題だと思うので、その問題の解決策がないことに非常に驚きます(make all && Sudo make installはどうですか)

9
Antoine Pelisse

あなたができる最善のことは、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
7
terdon

スクリプトを/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

9
roaima

Sudo!requirettyオプションとNOPASSWDオプションを使用することもできます。ただし、これによりセキュリティが低下することに注意してください。

0
Steve Wills

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_scriptAを実行します。 Aが正常に終了すると、スクリプトはA_is_doneというファイルを作成します。
  • 次にABC_scriptB_is_doneというファイルの存在をテストし、表示されるまでループします。
  • 並行して、B_scriptA_is_doneの存在を検出し、ループから抜け出します。 A_is_doneファイルを削除し、Bを実行します。 B_scriptはrootとして実行されているため、Bはrootとして実行されることに注意してください。 Bが正常に終了すると、スクリプトはB_is_doneというファイルを作成して終了します。
  • 並行して、ABC_scriptB_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が含まれている場合は続行し、それ以外の場合は終了します。

0
Scott