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


9

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

機能はB一方で、スーパーユーザーとして実行する必要がありますAし、Cしないでください。

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

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

    それは実行に悪いアイデアのように思えるAし、Cそれが必要ない場合は、スーパーユーザーとして

  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


3
sudoを使用して実行するスクリプトを作成することもできますが、スクリプトではとを使用して明示的にAC部分を実行しsu -l some_non_priviliged_userます。タイムアウトの問題はなく、AとCの特権もありません。4は可能ではないと思いますがsudo、ユーザーにとっては「グローバルな状態」のようです。
Anthon

回答:


7

あなたができる最善のことは、スクリプトを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

9

属性を指定して/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


最も安全なアプローチに賛成票を投じます。
eyoung100 2015年

0

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


1
問題は、対話型であることを、スクリプトを望んでいないとして定義されているように、と#2 /etc/sudoersのコマンドを実行するユーザのエントリBでは、NOPASSWD正しい答えです。
Andrew

それは「XかYができる」、それは「XとYができる」だった。両方だけが問題を解決します。おそらく私は私の答えを書き直す必要があります。
Steve Wills

0

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ルートとして。/がB正常に終了すると、スクリプトはというファイルを作成してB_is_done終了します。
  • 並行して、 ループのABC_script存在を検出しB_is_done、ループから抜け出します。B_is_doneファイルを削除します。B_scriptrootとして実行されたため、root B_is_doneが所有しrm -fており、確認のリクエストを取得しないようにするために使用することを忘れないでください。 ABC_scriptその後、実行Cして終了します。

さらなる改良のためのメモ:

  • ABC_scriptおそらくB_script、ではなく絶対パスで実行する必要があり./ます。
  • A_is_doneおよびB_is_doneABC_scriptはなく、ランダムで一意のファイル名を生成する必要があります。
  • 待機しているプログラムが終了したが失敗した場合に通知を受け取るには、スピン待機しているスクリプトの準備が必要です。(現在、A失敗した場合、両方のスクリプトは無限の待機ループに入ります。)これは、

    A  &&  > A_is_done

    A; echo $? > A_is_done

    次に、スピンウェイトを変更してX_is_doneファイルを読み取り、0が含まれている場合は続行し、それ以外の場合は終了します。


-3

ばかげている。多くの行を使用します。

if A; then

    if sudo B ; then
        C
    fi
fi

それは私の懸念をどのように解決していますか?問題とは何の関係もありません&&
Antoine Pelisse、2015年

&&は、最初のコマンドが失敗したときに実行を停止します。ifステートメントはこれをより詳細に行います。私のポイントは、たとえそれがきれいでなくても、あなたの仕事を成し遂げることです。
ロバートジェイコブス

1
これは、オプション2のより詳細なバージョンにすぎませんA && sudo B && C。アントワーヌが質問で説明するように; これはA、が完了するまでパスワードを要求しません。また、パスワードを待つ必要も、スクリプトが彼を待つ必要もありません。
スコット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.