
私は新しいパッケージをインストールして「自分でアップグレード」できるプログラムを開発しています。これを達成するために、at
コマンドを使用して今後1分後にシェルスクリプトを実行し、シェルスクリプトがパッケージをインストールすることを指定します。私はそれが次の瞬間に実行されることを心から願っていますが、マニュアルページで読んだ内容によると、これが私ができる最善のようです。より厳しい解像度でこれを行う方法はありますか?
答え1
プログラムを実行してすぐに更新を実行する方が簡単です(または本当に必要な場合は、少し遅れてスリープモードに切り替えることもできます)。
これがスクリプト自体(bashなど)にある場合は、更新スクリプトを直接呼び出します(出力をリダイレクトすることもできます)。
update-my-thingy < /dev/null > /dev/null 2>&1
プログラムにいる場合は、いつでもsystem()呼び出しを使用して同じことを実行できます。
system("update-my-thingy < /dev/null > /dev/null 2>&1");
答え2
答え3
プログラムが実行する操作によって異なります。デーモンの場合、次のように実行されます。
- 実行可能ファイルの寿命の確認
- 期間がプログラムの開始時間より短い場合は、実行可能ファイルを新しいバージョンで上書きします。
- このような場合は、何をすべきか(またはしないでください)作業がないまで待ってください。
exec()
新しいバイナリでプログラムを直接再起動します。
答え4
これはトリッキーです。まず、予防策としてスクリプトの先頭に関数呼び出しを入れて、最後まで呼び出さないでください。
% killmenow() { ... }
...
% killmenow
EOF
これは、現在のスクリプトのすべての内容を完全に読み取り、メモリにコピーしたことを確認するための最良の方法です。ちょうど言うよ。
今答えようとしています...
POSIXは、jobs
これらの操作のためのユーティリティを指定します。具体的には、、wait
の組み合わせが最も安全だとtrap
思います。kill
できるだけきちんと作業を進めるには、次のようにします。newgrp
繰り返しますが、これはexec
遺伝的特性の点で非常に似ていますが、この場合は非常に重要ですprocess id
。
さて、たくさん聞こえるのはわかりますが、最終的には見ることはあまりありません。
% suicide() { _me="${1}" ; (
>> trap 'wait "${_me}" && set -- &&\
>>> eval `newgrp && exec { YOUR | CMD | HERE }`' INT &&\
>> kill -s INT "-${_me}"
>> ) & }
...
% suicide "${$}"
いいですね。ワークフローは次のとおりです。
suicide
まず、スクリプト全体をロードして実行します。最後の行までこれをしないので確信しています。suicide
コピーを渡しprocess id
て保存します$_me
。この場合、内部から簡単にインポートできますが、suicide
他の場所でも使用できます。trap
サブシェルはスキャンを呼び出し、trapped
'$cmd'
噂の呼び出しを監視するように指示しますINT
。kill
もちろん、私たちが最後の要求をすることができるようにすべての準備ができています。kill
私たちに渡されただけでなく、プロセスグループ全体がそれを受け取ることを指定しました。恐れてはいけません - システム全体が狂ってしまわない限り - 今は殺すことができないものを殺すことはできません。また、パラメータを指定する必要はありません。ただ徹底したかっただけです。INTERRUPT SIGNAL
$_me
-
$_my
$_me
$_me
-
kill
PID
わかりましたが、まだ終わっていませんか?いいえ。コマンドセット全体を&
バックグラウンドサブシェルに入れて、応答を続けてtrap
応答できるようにしますINT
。
- それを受け取ったら
INT
今trap
評価してください'quoted argument'
。その文字列内のすべての項目が今だけ取り出されていることを覚えておくことが重要です。$_me
他の場所で解決すべき答えがない質問がある場合に備えて、trap
まず電話してください。wait
$_me
その上必要な場合にのみ入場に固執します。。- 準備が完了したら、残りを拭き取り、事業を始めました
env $vars
。set --
newgrp
実行するように設計されていますinteractive shell
。このようにきれいなエスケーププロセスを必ずしも提供する必要はありません。実際にシステムにgroup
パスワードが必要な場合(そうではありません)、このパスワードは機能せず、今は消えます。
私はこの方法を呼ぶ。狡猾な以下では、POSIXガイドから直接インポートします。
これの一般的な実装は、
newgrp
現在のシェルが自分exec
自身を上書きし、グループを変更newgrp
して新しいシェルで自分自身を上書きすることです。
それでは、次の段落で...
newgrp コマンドは対話型端末でのみ使用できます。アプリケーションをサポートするのに役立つインターフェイスを提供しません。
したがって、狡猾な部分は、eval
保存や再利用などのこの種の作業に非常にうまく機能できることです"$@"
。しかし、後でおそらく...
- 代わりに、インタラクティブプロンプトで次のコマンドのみを取得する別のプロセスを最初にロードするステートメントを間接的に使用し、次に隠し
eval
バックドアを追加します。newgrp && exec
exec
{ YOUR | CMD }
この時点で、クリーンな環境の新しいプロセスグループにある新しいシェルで新しいスクリプトを実行し、プロセスが完全に完了するのにかかる時間だけ待つ必要があります。
実際、私たちは徹底的に安全にすることができます。
...exec { wget -O - "${URL}" >"${0}" ; exec "${0}" }