私はdd
次のプログラムのマンページを理解しようとしています。
実行中の「dd」プロセスにUSR1シグナルを送信し、I / O統計を標準エラーとして印刷してからレプリケーションを再開します。
$ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid
どういう意味ですかpid=$!
?
これは変数への割り当てですか? pidを取得しますかdd
?最終的に$pid
変数に使用されますか?
また、なぜ使用するsleep
のですkill
か?
使用方法は-USR1
?
答え1
dd if=/dev/zero of=/dev/null&
末尾とは、&
バックグラウンドで prefix コマンドを実行することを意味します。 (免責事項:これは過度に単純化された声明です)
引用するこれ:
$!最新のバックグラウンドコマンドのPID。
だからpid=$!
割り当て最新の背景PIDPIDは変数pidにdd
。
そしてなぜ彼らは眠りに落ちて殺すのですか?
あなたはする必要がありますkill $pid
(パラメータが指定されていない場合、killのデフォルト信号はTERMであり、これはプロセスが終了することを意味します。)dd
テストが完了したら、プロセスを終了します。そうしないと、dd
プロセスはバックグラウンドに残り、CPUリソースを消費する可能性があります。プラットフォームのシステムモニターを確認して確認してください。
I / O統計は印刷されますが、Kill -USR1 $pid
プロセスは終了しません。
dd
1秒待機しないと、プロセスが端末に統計出力を書き込む前に、最後のステートメントによってプロセスが終了する可能性があります。kill $pid
これらのプロセスは同期されますが、トラップ+書き込み操作( kill -USR1 $pid
) は次より遅くなることがあります。ジョブ終了(kill $pid
)。したがって、2番目は、統計出力の印刷が完了したことを確認するためにsleep 1
開始を遅らせることです。kill $pid
これが-USR1が使用される方法ですか?
のみman dd
:
実行中の「dd」プロセスにUSR1シグナルを送信し、I / O統計を標準エラーとして印刷してからレプリケーションを再開します。
そしてman 7 signal
:
SIGUSR1 30,10,16 Term User-defined signal 1 SIGUSR2 31,12,17 Term User-defined signal 2
これら2つの文を組み合わせると、USR1が次のようになることを理解する必要があります。カスタム信号その定義は、dd
ユーザーにこれを中断する方法を提供することです。I/O 統計の印刷飛行中。これはプログラム固有のハンドラであり、kill -USR1 other_program_pid
統計出力を期待できるという意味ではありません。
また、に興味がある可能性があります注:SIGUSR1がプロセスを終了するのはなぜですか?。
答え2
USR1
これは信号の使用を説明するためのデモですdd
。
dd if=/dev/zero of=/dev/null &
dd
バックグラウンドで始まると、データは(プログラムが読み取るたびにゼロを生成する)から(書き込まれた内容をすべて削除)/dev/zero
にコピーされます。/dev/null
これはdd
実験に使用できる無害なインスタンスを提供します。これは、ストレージスペースを消費せずに必要なだけ実行できるため、ユーザーが信号を送信する時間を提供します。
pid=$!
最後のバックグラウンドコマンドのプロセス識別子を$!
変数に保存しますpid
。
kill -USR1 $pid
識別子が変数(この場合は背景)USR1
に格納されている値であるプロセスにシグナルを送信します。この信号を受信すると、現在の進行状況(読み書きしたデータ量)を印刷してコピーを続けます。pid
dd
dd
sleep 1
ちょっと待って。
kill $pid
TERM
に信号を送信して終了するdd
ようにしますdd
。 (バックグラウンドで実行することはここでは意味がありませんdd
。)
上記の2行目の代わりにこれを実行するとより有益です。
kill -USR1 $pid; sleep 1; kill -USR1 $pid; kill $pid
dd
進行状況を表示するには、1秒間隔で進行状況を2回出力し、待機せずに終了しますdd
。
実際の使用には、dd
元のコマンドの適切な入力と出力(いくつかの追加オプションを含む)を指定し、最後のコマンドを実行せずにそれ自体が完了するのを待ちkill
ます。dd
USR1
最後の質問に答えるために、シェル(または他のシグナル)からシグナルを送信する方法は次のとおりです。kill
送信される信号と、信号が送信されるプロセスのプロセス識別子(またはジョブ識別子)を含みます。使用できるその他(POSIX以外)コマンドは次のとおりです。pkill
そしてkillall
、名前でプロセスを探したいとき。
答え3
ほとんどまたはすべてのシェルの場合、$!
シェルから分岐した最後のプロセスのプロセスID(PIDとも呼ばれます)。このdd
コマンドはフォークを使用して、フォークの右側にプロセスIDをシェル変数に割り当てます&
。pid=$!
dd
dd
pid
プロセスIDは、LinuxまたはUnixでいくつかのコードが実行されるアドレス空間を参照するために使用される番号です。
プログラムkill
名は、その目的がプロセスにシグナル(小さな非同期メッセージ)を送信することであるため、直感的ではありません。約128個の信号のみがあり、すべて番号と名前が付けられています。たとえば、「kill」信号は数値 9 です。 USR1 は数値 10 として定義されます。したがって、kill -USR1 $pid
信号10はプロセス番号で送信されます$pid
。dd
時には実行に長い時間がかかるため、これは前dd
に分岐してバックグラウンドで実行されたコマンドのプロセスIDであることがほぼ確実です。このkill $pid
コマンドは、同じプロセスIDにTERM信号を送信します。 TERMは「終了」を意味します。よく書かれたプログラムは通常TERMをキャプチャし、割り当てられたリソースをクリーンアップして終了します。
dd
なぜバックグラウンドで実行し、USR1信号を送信して1秒待ってから、すべてのdd
リソースを解放して終了するのかわかりません。完全なコードスニペットでは、dd
実行するのに長い時間がかかると仮定しているようですが、そうではありません。私の考えでは、このコードには競争条件があり、あなたが望む意味が何であれ実際には得られないかもしれません。
答え4
dd
コマンドをフォアグラウンドで実行し、現在の進行状況を表示したい場合。status=progress
フラグを使用してコマンドを実行してみてください。
sudo dd if=/dev/sda of=/dev/sdb status=progress
これにより、進行状況が動的に表示されます。
これは、12.0(2018)以降のFreeBSDでの実装にも使用できるGNU実装dd
(2015年にリリースされたバージョン8.24に追加)への拡張ですが、通常、他のBSDでの他の実装は除外されます。dd