インストールスクリプトの実行中に一時的にsudoのタイムアウトを増やす


22

たくさんのソフトウェアをインストールするスクリプトを作成しようとしていますがroot、すべてをとして実行する必要はありませんので、パスワードの入力を求めてから、sudoまたはsu必要なときに特権を取得します。

私がやっていたsudo -vスクリプトの先頭にパスワードを要求するようにして、ちょうど通常、後にsudoを使用します。タイムアウトを引き継ぐ単一のインストールに到達するまで、これはうまく機能します。

タイムアウトを永続的に増やす必要はありません。現在のセッションでのみsudoのタイムアウトを増やす方法はありますか?

回答:


8

バックグラウンドで実行されるループをセットアップして、定期的に「sudo -v」を実行できます。もちろん、スクリプトが終了したときにループを完全に終了させるのがコツです。そのため、2つのプロセス間に何らかのタイプの通信が必要です。tmpファイルはこれには問題なく、スクリプトの実行後にも簡単にクリーンアップできます。(とにかく、インストールスクリプトが通常これを行います。)

たとえば(これを使用するには 'echo'ステートメントを削除します。これらは単に「機能している」ことを示しています):

#!/bin/bash
log=running_setup.txt
sudo_stat=sudo_status.txt

echo "========= running script $$ ========"
echo $$ >> $sudo_stat
trap 'rm -f $sudo_stat >/dev/null 2>&1' 0
trap "exit 2" 1 2 3 15

sudo_me() {
 while [ -f $sudo_stat ]; do
  echo "checking $$ ...$(date)"
  sudo -v
  sleep 5
 done &
}


echo "=setting up sudo heartbeat="
sudo -v
sudo_me

echo "=running setup=" | tee $log
while [ -f $log ]
do
 echo "running setup $$ ...$(date) ===" | tee -a $log
 sleep 2
done

# finish sudo loop
rm $sudo_stat

その後、表示されます(注:pidはtmpファイルに格納されます。簡単に削除できるようにするためです。ただし、必ずしも必要ではありません)。

$ ./do_it.sh
========= running script 6776 ========
=setting up sudo heartbeat=
[sudo] password for user: 
=running setup=
checking 6776 ...Wed May  4 16:31:47 PDT 2011
running setup 6776 ...Wed May  4 16:31:48 PDT 2011 ===
running setup 6776 ...Wed May  4 16:31:50 PDT 2011 ===
running setup 6776 ...Wed May  4 16:31:52 PDT 2011 ===
checking 6776 ...Wed May  4 16:31:53 PDT 2011
running setup 6776 ...Wed May  4 16:31:54 PDT 2011 ===
<ctrl-c>  (cleans up files, then exits)

9

私はmichael_nの答えが好きでしたが、一時ファイルを使用したくないという最も非合理的な欲求がありました。たぶん、これはいくつかの見通しを提供することができます。

私の解決策は:

#!/bin/bash
function sudo_ping() {
    if [[ ! -z $SUDO_PID ]]; then
        if [[ $1 -eq stop ]]; then
            echo "Stopping sudo ping in PID = $SUDO_PID"
            kill $SUDO_PID
            return
        else
            echo "Already sudo pinging in PID = $SUDO_PID"
            return
        fi
    fi

    echo "Starting background sudo ping..."
    sudo -v
    if [[ $? -eq 1 ]]; then
        echo "Oops, wrong password."
        return
    fi
    sudo echo "ok"

    while true; do
        echo 'Sudo ping!'
        sudo -v
        sleep 1
    done &
    SUDO_PID=$!
    sudo echo "Sudo pinging in PID = $SUDO_PID"

    # Make sure we don't orphan our pinger
    trap "sudo_ping stop" 0
    trap "exit 2" 1 2 3 15
}

sudo_ping
sleep 5
echo "Goodbye!"

繰り返しますが、これらechoは無関係です...

$ ./sudoping.sh 
Starting background sudo ping...
Password:
ok  
Sudo ping!
Sudo pinging in PID = 47531
Sudo ping!
Sudo ping!
Sudo ping!
Sudo ping!
Goodbye!
Stopping sudo ping in PID = 47531

繰り返しますが、ctrl-cも機能します...

$ ./sudoping.sh 
Starting background sudo ping...
ok  
Sudo ping!
Sudo pinging in PID = 47599
Sudo ping!
^CStopping sudo ping in PID = 47599

6
より簡潔なソリューション:gist.github.com/3118588
グレゴリーパーキンス

これにはどうして1000以上のアップ投票がありませんか???簡潔なバージョンは素晴らしいです。(しかし、より良い例が役立つと思います。)
Monica CellioのMountainX

3

この要点に基づいて、簡潔でクリーンなバージョンを作成しました。

# Prevent sudo timeout
sudo -v # ask for sudo password up-front
while true; do
  # Update user's timestamp without running a command
  sudo -nv; sleep 1m
  # Exit when the parent process is not running any more. In fact this loop
  # would be killed anyway after being an orphan(when the parent process
  # exits). But this ensures that and probably exit sooner.
  kill -0 $$ 2>/dev/null || exit
done &

sudo -Kシェルスクリプトの他の場所で呼び出された場合、バージョンはsudo: a password is required毎分stderrに叫ぶので、要点バージョンの方が良いと思います。
Rockallite

@Rockallite私のリンクの要旨ですか?実際には同じです。
ボーア

0

sudomanページによると:

   -v          If given the -v (validate) option, sudo will update the user's time stamp,
               prompting for the user's password if necessary.  This extends the sudo timeout for
               another 15 minutes (or whatever the timeout is set to in sudoers) but does not run
               a command.

したがってsudo -v、セッションを検証するために(開始時だけでなく)セットアップスクリプトのいくつかのポイントを追加すると、必要なものが得られると思います。タイムアウトに達しました)。唯一の問題は、タイムアウトよりも時間がかかるコマンドがスクリプトにある場合です(したがって、すぐに検証しても、タイムアウトは別の検証が完了する前に期限切れになります)が、これは非常に特殊なケースです。

起こることは、使用するだけでsudoはタイムアウトが増加sudo -vせず、コマンドを実行しないためsudo -v、セッションを検証するためにより多くの時間を使用する必要があるということです。


そう、ありがとう。問題は、私のsudoタイムアウトが5分に近いことであり、それをはるかに超える単一のmake installコマンドがあります。
アレリウス

うーん まあ。タイムアウトを大きくすること以外にやることはあまりありません。一時的に設定する方法はありません。
コアダンプ

0

上の基本骨子が提供するグレゴリー・パーキンスと私の経験では、ここに私のワンライナーです:

trap "exit" INT TERM; trap "kill 0" EXIT; sudo -v || exit $?; sleep 1; while true; do sleep 60; sudo -nv; done 2>/dev/null &

または

trap "exit" INT TERM
trap "kill 0" EXIT
sudo -v || exit $?
sleep 1
while true; do
    sleep 60
    sudo -nv
done 2>/dev/null &

説明

  • trap "exit" INT TERM; trap "kill 0" EXIT:これにより、終了またはSIGINT / SIGTERMでプロセスツリー全体が停止します。

  • sudo -v || exit $?:事前にパスワードを要求し、セキュリティ資格情報をキャッシュしますが、コマンドは実行しないでください。パスワードが正しくない場合は、sudoから返されたコードで終了します。

  • sleep 1:セキュリティ資格情報が効果的に保存されるように、少し遅れます。次のsudoの実行が早すぎる場合、資格情報がまだ保存されていないため、それを認識できません。したがって、再度パスワードを要求します。

  • while true; do sleep 60; sudo -nv; done 2>/dev/null &:既存のsudoセキュリティ資格情報を繰り返し更新します。このバージョンは、リンクされた要点のバージョンとは異なることに注意してください。sleep 60最初に実行され、次に実行されsudo -nvます。

    • &オペレータは、全体置くwhile子プロセスとして実行し、バックグラウンドにループを。

    • 2>/dev/nullstderrのリダイレクトwhileループ内の任意のコマンドによって生成されたエラーメッセージが破棄されますので、無効にループを。

    • -nオプションはsudo、ユーザーにパスワードの入力を求めることを防ぎますが、パスワードが必要な場合はエラーメッセージを表示して終了します。

    • 何もありませんkill -0 "$$" || exit最初の2つのので、リンクされた要旨のようにtrapsが仕事を行います。親プロセスが実行されていないことがわかるまで、59秒間スリープする必要はありません!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.