一連のソフトウェアをインストールするスクリプトを記述しようとしています。すべてをroot
として実行する必要がないようにしたいので、パスワードの入力を求めてから、インストールについては、Sudo
またはsu
を使用して、必要なときに権限を取得します。
Sudo -v
toスクリプトの最初にパスワードの入力を要求し、後で通常どおりSudoを使用します。これは、タイムアウトを引き継ぐ単一のインストールに到達するまではうまく機能します。
タイムアウトを永続的に増やす必要はありません。現在のセッションでのみSudoのタイムアウトを増やす方法はありますか?
バックグラウンドで実行されるループを設定して定期的に「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)
私は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
これに基づいて Gist を使用して、簡潔でクリーンなバージョンを作成しました。
# 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 &
GistGregory Perkins によって提供されるベースと私の経験、これが私の1行です:
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の実行が早すぎる場合は、資格情報がまだ保存されていないため、Sudoはそれを認識せず、パスワードを再度要求します。
while true; do sleep 60; Sudo -nv; done 2>/dev/null &
:既存のSudoセキュリティ認証情報を繰り返し更新します。このバージョンは、リンクされたGistのバージョンとは異なります。最初にsleep 60
、次にSudo -nv
を実行します。
&
演算子は、while
ループ全体をバックグラウンドに配置し、子プロセスとして実行します。
2>/dev/null
は、while
ループのstderrをvoidにリダイレクトするため、ループ内のコマンドによって生成されたエラーメッセージは破棄されます。
Sudo
の-n
オプションは、ユーザーにパスワードを要求することを防ぎますが、パスワードが必要な場合はエラーメッセージを表示して終了します。
最初の2つのtrap
sが機能するため、リンクされたGistのようなkill -0 "$$" || exit
はありません。親プロセスが実行されていないことがわかるまで、59秒間スリープする必要はありません。
Sudo
manページによると:
-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
をさらに使用する必要があります。