dd
プログラムのマンページを理解しようとしています。
実行中の「dd」プロセスにUSR1シグナルを送信すると、I/O統計が標準エラーに出力され、コピーが再開されます。
$ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid
pid=$!
の意味?
これはdd
のPIDを取得する変数の割り当てですか?そして、最終的に$pid
変数で使用されますか?
また、なぜsleep
とkill
を使用するのですか?
これは-USR1
を使用する方法ですか?
dd if=/dev/zero of=/dev/null&
末尾の&
は、バックグラウンドでprefixコマンドを実行することを意味します。 (免責事項:これは過度に単純化されたステートメントです)
this を参照してください:
$!最新のバックグラウンドコマンドのPIDです。
したがって、pid=$!
は、最新のバックグラウンドPIDを変数pidに割り当てます。これは、dd
PIDです。
また、なぜ彼らは睡眠と殺害を使うのですか?.
テストの終了後にdd
プロセスを終了するには、kill $pid
を指定する必要があります(パラメーターが指定されていない場合、killのデフォルトのシグナルはTERMです)、それ以外の場合はdd
プロセスはバックグラウンドにとどまり、CPUリソースを使い果たす可能性があります。お使いのプラットフォームのシステムモニターを確認してください。
Kill -USR1 $pid
はI/O統計を出力しますが、プロセスを終了しません。
1秒のスリープがないと、統計情報出力を端末に書き込む前に、dd
プロセスが最後のコマンドステートメントkill $pid
**によって終了する場合があります。プロセスは同期していますが、trap + write操作(kill -USR1 $pid
)は、terminate operation(kill $pid
)。したがって、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
両方のステートメントを組み合わせると、USR1がユーザー定義のシグナルであり、ユーザーがそれを中断する方法を提供するdd
によって定義され、I/O統計情報を印刷します。これはプログラム固有のハンドラーであり、kill -USR1 other_program_pid
を使用して統計情報の出力を期待できるという意味ではありません。
また、あなたは興味があるかもしれません これ:なぜSIGUSR1はプロセスを終了させるのですか? 。
これは、dd
でのUSR1
信号の使用法を示すデモにすぎません。
dd if=/dev/zero of=/dev/null &
dd
をバックグラウンドで開始し、/dev/zero
(プログラムが読み取ると常にゼロが生成されます)から/dev/null
(書き込まれたものをすべて破棄する)にデータをコピーします。これは、実験に使用できるdd
の無害なインスタンスを提供します—ストレージを使い果たすことはなく、必要なだけ実行し続けるため、ユーザーに信号を送信する時間を与えますそれに。
pid=$!
最後のバックグラウンドコマンド($!
)のプロセス識別子を変数pid
に格納します。
kill -USR1 $pid
USR1
シグナルを、識別子がpid
変数(この場合はバックグラウンドdd
)に格納されている値であるプロセスに送信します。 dd
がこの信号を受信すると、現在の進行状況(読み書きされたデータの量)を出力し、コピーを続行します。
sleep 1
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
です。
ほとんどまたはすべてのシェルの場合、$!
は、シェルが分岐した最後のプロセスのプロセスID(PIDとも呼ばれる)です。 dd
コマンドは&
でフォークされたため、dd
をフォークした直後のpid=$!
はdd
プロセスIDをシェル変数pid
に割り当てます。
プロセスIDは、LinuxまたはUnixがアドレススペースを参照するために使用する番号で、コード内で実行されているコードがあります。
kill
プログラムの目的はプロセスにシグナル(小さな非同期メッセージ)を送信することであるため、わかりにくい名前があります。信号はほんのわずかで、合計で128です。それらには、番号と名前の両方があります。たとえば、「キル」信号は9番です。 USR1は番号10として定義されています。したがって、kill -USR1 $pid
は$pid
と番号が付けられたプロセスにシグナル10を送信します。 dd
の実行には時間がかかる場合があるため、これはほぼ確実に、以前に分岐されてバックグラウンドで実行されたdd
コマンドのプロセスIDです。 kill $pid
コマンドは、TERMシグナルを同じプロセスIDに送信します。 TERMは「終了」を意味します。適切に作成されたプログラムは通常TERMをキャッチし、割り当てたリソースをクリーンアップして終了します。
dd
をバックグラウンドで実行してUSR1シグナルを送信し、1秒待ってからdd
がすべてのリソースの割り当てを解除して終了する理由は完全にはわかりません。コード全体では、dd
が長時間実行されると想定しているようですが、そうではない場合があります。このコードには競合状態があり、必要なセマンティクスが何であれ、実際にはそれらを取得できない場合があると思います。