1分より速い実行遅延?

1分より速い実行遅延?

私は新しいパッケージをインストールして「自分でアップグレード」できるプログラムを開発しています。これを達成するために、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

数秒待つスクリプトをフォークします。

{ sleep 5; update-my-program; } &

プログラムが終了した直後にアップグレードすることが目標であり、以前はアップグレードしない場合は、次を呼び出してプログラムの終了をスケジュールしてください。execve変えるexit。システムexecveコールは現在のプログラムを他のプログラムに置き換えます。 Cには、引数の伝達方法に応じてさまざまなバリエーションがexeclあります。execpシェルから対応する組み込みはexec

答え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-killPID

わかりましたが、まだ終わっていませんか?いいえ。コマンドセット全体を&バックグラウンドサブシェルに入れて、応答を続けてtrap応答できるようにしますINT

  • それを受け取ったらINTtrap評価してください'quoted argument'。その文字列内のすべての項目が今だけ取り出されていることを覚えておくことが重要です。
  • $_me他の場所で解決すべき答えがない質問がある場合に備えて、trapまず電話してください。wait$_meその上必要な場合にのみ入場に固執します。
  • 準備が完了したら、残りを拭き取り、事業を始めましたenv $varsset --

newgrp実行するように設計されていますinteractive shell。このようにきれいなエスケーププロセスを必ずしも提供する必要はありません。実際にシステムにgroupパスワードが必要な場合(そうではありません)、このパスワードは機能せず、今は消えます。

私はこの方法を呼ぶ。狡猾な以下では、POSIXガイドから直接インポートします。

これの一般的な実装は、newgrp現在のシェルが自分exec自身を上書きし、グループを変更newgrpして新しいシェルで自分自身を上書きすることです。

それでは、次の段落で...

newgrp コマンドは対話型端末でのみ使用できます。アプリケーションをサポートするのに役立つインターフェイスを提供しません。

したがって、狡猾な部分は、eval保存や再利用などのこの種の作業に非常にうまく機能できることです"$@"。しかし、後でおそらく...

  • 代わりに、インタラクティブプロンプトで次のコマンドのみを取得する別のプロセスを最初にロードするステートメントを間接的に使用し、次に隠しevalバックドアを追加します。newgrp && execexec{ YOUR | CMD }

この時点で、クリーンな環境の新しいプロセスグループにある新しいシェルで新しいスクリプトを実行し、プロセスが完全に完了するのにかかる時間だけ待つ必要があります。

実際、私たちは徹底的に安全にすることができます。

...exec { wget -O - "${URL}" >"${0}" ; exec "${0}" }

関連情報