cat
テキストファイルの内容を調整すると、すべての内容が印刷され、コマンドが終了します。ただし、これを行うcat /dev/ttyS0
と、コマンドが中断され、新しいデータが到着するのを待ちます。
このように一時停止するのはなぜですか?
答え1
cat
端末での実験
cat
より多くのデータを待つ理由は次のとおりです。クエンムと言う。入力が端末になるように入力してcat
押しても同じことが発生します。Enter端末で動作を簡単に試すことができますcat
。まず、実行方法は次のとおりです。
端末にCtrl+を入力すると、D端末はリテラルCtrl+D文字をプログラムに送信しません。これを行うには、Ctrl+を入力してV次の制御文字を文字通り処理する必要があることを端末に通知し、Ctrl+を入力する必要がありますD。代わりに:
- 入力バッファにテキストがある場合(つまり、まだプログラムに送信されていないテキストを入力した場合)、バッファはフラッシュされます。これは、そのテキストがプログラムに送信されたことを意味します。プログラムは、次回を読むとそれを受け取ります。
- 入力バッファにテキストがない場合、端末はプログラムへの入力の終わりを示し、その結果、プログラムは次の読み取り操作でファイル終了条件に直面します。これは実際には(下記参照)です。現在のこの場合、読み取り操作はすでに
cat
読み取り中であるためです。
Enter指示を除外する改行文字、返品Ctrl+を押さなくてもバッファはフラッシュされますD。したがって、あなたは以下を観察するでしょう:
テキストを入力してEnterまたはCtrl+を押すと、同じテキストが端末に書き込まれDます。を
cat
使用すると、Enter改行cat
文字も作成されます。Enter行の先頭で押すかCtrl+を押して、D改行文字を送って
cat
書き込みます。行の先頭で+を押すかCtrl+を押して(つまり、2回連続して)入力を終了します。DCtrlD
cat
最後の入力ソースから読み取ることがないことを確認すると(「cat」は「catenate」または「concatenate」を意味し、これは複数のファイル名引数を受け取ったときに機能する方法です)終了します。
制御端末からの読み込みが完了するまで入力を待つのと同様にcat
、読み込みを指示すると、他のファイルやデバイス(シリアル端末を含む)からの追加入力を待ちます。
CtrlD+と関連する特別な動作により、Enter入力がに送信されますcat
。あなたの端末、代わりにcat
。特に、cat
それ自体は改行文字を特に扱いません。
待機プロセスの状態
cat
入力を待っている間は、他の端末でステータスを確認してください。
ほとんどのUnixファミリーオペレーティングシステムでは、またはpidof cat
を実行して実行中のすべてのcatプロセスのプロセスIDを見つけることができますpgrep -x cat
。少なくとも一つ一般的にサポートされています。または、実行中の同じ端末で+を押して一時Ctrl停止します。Zcat
実際にプロセスを一時停止してから実行してps
PIDを見つけ、それを実行して再起動しますfg
。または、tty
最初の端末で実行して端末装置のパス名を表示します。 GNU/Linux では次のようになります。/dev/tty2
または/dev/pts/4
--then run cat
、 2番目の端末で実行、交換ps -t tty
tty
tty
最初の端末の出力です。
2番目の端末で交換した場所を実行してください。ps pid
pid
catプロセスの実際のプロセスIDを使用します。ステータスを表示する列を含むプロセスが一覧表示されます。 (上記のコードを実行しても、tty -t
以前にステータス列が含まれていなかったGNU / Linuxを含む一部のシステムではこれが必要です。)
たとえば、GNU/Linux システムでは、次のようにします。
ek@Io:~$ ps 30196
PID TTY STAT TIME COMMAND
30196 pts/4 S+ 0:00 cat
あなたの外観は異なって見えるかもしれません。 STATまたはS列の下に表示されるプロセスステータスコードを実行して検索することをお勧めしますman ps
。これらのコードはシステムごとに少し異なります。その GNU/Linux システムでは参考(1)表示プロセスの状態は次のように報告されました。
S interruptible sleep (waiting for an event to complete)
+ is in the foreground process group
そのGNU / Linuxシステムで上記のように+をcat
使用して実行し、一時停止するとCtrl次のように変更されます。ZS+
T
T stopped by job control signal
睡眠は邪魔になる可能性があるためノンストップ睡眠?例:
D uninterruptible sleep (usually IO)
これは通常、プロセスがカーネルがキャンセルを許可しないIO操作を実行したときに発生します。中断せずに省電力状態のプロセスは終了できません。またはを使用すると、ジョブが完了するとTERMまたはKILL信号をそれぞれ受信します。kill pid
kill -9 pid
追跡プロセス
gdb
通常、プログラムをデバッグするには、またはなどのデバッガでプログラムを開きますlldb
。ただし、GNU/Linux を含む一部のシステムには、strace
次のプログラムがあります。システムコールプロセスが進行中です。端末で入力を待つプロセスを実行するには、端末のプロセスにさらに入力が送信されるまで実行をブロックするstrace
各呼び出しを表示できます。read
Fedora、CentOS、Debian、UbuntuなどのGNU / Linuxシステムがある場合(これらは例にすぎず、他のシステムもたくさんあります)、次のコマンドを実行してみてください。
strace cat
一連のシステムコールを表示できます。まず、プロセスを実行する呼び出し(execve
プログラムが共有ライブラリを使用している場合は、ファイル名に関連するさまざまな呼び出しが続きます。これはほぼ確実です)とほとんどのプログラムで実行される呼び出しです。そして...をld.so
含むCライブラリ関数が機能するようにし、最終的には読みます。mmap
brk
標準入力:
read(0,
これは構文ですstrace
。プロセスcat
は次のとおりです。いいえ文字通りパラメータを渡す過程でread
(構文は以前に使用していなかったCプログラマと似ているように見えるかもしれないのでstrace
)。代わりにread
システムコールを実行します。まだ返されていません。。データが読み込まれたか、入力の終わりに達すると返されます。
たとえば、と入力してfoo
を押しますEnter。これにより、次の内容が表示されます。
"foo\n", 131072) = 4
write(1, "foo\n", 4foo
) = 4
read(0,
それはどういう意味ですか?終了しcat
(Ctrl行の先頭に+追加または任意の場所に+追加)、リダイレクトして出力を抑制しながら再実行すると、見やすくなります。DCtrlC/dev/null
strace cat >/dev/null
strace
作成したとおりに出力を表示できます。標準エラーそしてあなたはリダイレクトだけしました。標準出力。ただし、現在のcat
出力foo
とユーザーが提供した改行文字は表示されません。入力して押したfoo
後に表示される内容はEnter次のとおりです。
"foo\n", 131072) = 4
write(1, "foo\n", 4) = 4
read(0,
つまり、read
呼び出しが完了して読み取りfoo
の後に表示される改行文字が続きます\n
。cat
その後、呼び出しはwrite
同じ文字列を出力に書き込みます。 Cコードには呼び出しがない可能性がありますcat
。write
代わりに、Cライブラリ関数(またはfprintf
)を使用して書き込みを実行できます。これはシステムコールではなく、最終的にシステムコールを使用して機能するため、fputs
出力には表示されません。が渡され、カーネルに4バイトを書く必要があることを伝えます。strace
write
4
write
f
o
o
\n
入力を読み続けるには、thisを呼び出してからwrite
もう一度cat
呼び出します。read
引き続き入力を与え、callを確認してwrite
からread
再度呼び出すことができます。たとえば、次のように入力してタップしabracadabra
ますEnter。
"abracadabra\n", 131072) = 12
write(1, "abracadabra\n", 12) = 12
read(0,
完了したら、最後の項目を入力してEnter(または+)を押し、次にCtrl+を押します。入力が終了すると終了し、以下が表示されます。DCtrlDcat
strace
read(0, "", 131072) = 0
munmap(0x7f856a591000, 139264) = 0
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++