追加端末?

追加端末?

私はLinuxを学んでいます。プロセスを端末に貼り付けることができるというアイデアが浮上しました。端末(TTY)にプロセスを接続することはどういう意味ですか?なぜこれを行うべきですか?

答え1

メモ: Unixの仕事のコントロールをよりよく理解するために、このトピックのウィキペディアページに案内します。ジョブ制御(Unix)


追加端末?

「ターミナルに接続する」というフレーズは、通常、シェルのコンテキストでタスクについて話すときに聞くことです。しかし、それは他の意味も持っています。 「ターミナルへのプロセスの接続」という語句は、gdb特定のプロセスID(PID)に接続し、情報を一覧表示または監視するなどのstraceツールを使用することを意味します。lsof

これらの両方について議論する予定ですが、まず作業キューについて議論します。なぜなら、それがあなたが探しているキューだと思うからです。

背景 - ジョブキュー

Unixファミリーのオペレーティングシステムでは、一般にタスクという概念を見ることができます。通常、私が使用したほとんどのUnixファミリーオペレーティングシステムでも同様の方法で動作します。つまり、バックグラウンドで実行でき、キュー(ジョブキュー)に番号を割り当てることができ、そのジョブキュー内の番号のコンテキストに従って操作できます。

ジョブキューに何かを入れるために、この動作をバックグラウンド処理と呼びます。すでにバックグラウンドで実行されているジョブを再開している場合は、これをフォアグラウンド処理と呼びます。これを行う一般的なコマンドbgはですfg&実行するコマンドの最後に「&」記号を使用して、ジョブをバックグラウンドに即座に切り替えることもできます。

はい

働く

$ sleep 2 &
[1] 19189

ここでは、sleepコマンドを2秒間実行し、バックグラウンドに入れました。出力は、ジョブキュー番号([1])やバックグラウンドジョブのプロセスID 19189などの便利な情報をすぐに提供します。

これが最終的に終了すると、実行中の端末に次のメッセージが表示されます。

$
[1]+  Done                    sleep 2

前景と背景

バックグラウンドジョブに対してアクションを実行するには、次のようにします。

$ sleep 20 &
[1] 19207

$ fg
sleep 20
^C

ここでは、ジョブをバックグラウンド(&)に送信してからフォアグラウンド()に戻し、fg+ CtrlC^Cコマンドを使用してジョブを終了します。

バックグラウンドタスクが複数ある場合:

$ sleep 20 &
[1] 19224
$ sleep 20 &
[2] 19225
$ sleep 20 &
[3] 19226
$ jobs
[1]   Running                 sleep 20 &
[2]-  Running                 sleep 20 &
[3]+  Running                 sleep 20 &

私たちはコマンドを使ってそれらを見ることができますjobs。 #3と#2の横にある小さな合計を確認してください+。ジョブキュー番号を指定せずにコマンドを-実行すると、fg最後のジョブがジョブキュー()に追加されます+。たとえば、

$ fg
sleep 20
^C

$ jobs
[1]-  Running                 sleep 20 &
[2]+  Running                 sleep 20 &

殺す

ジョブキュー番号を使用してジョブを処理できます。一つの方法はそれらを殺すことです。ジョブキュー番号を参照するには%他のコマンドと一緒に参照する場合は、その番号の前にプレフィックスを付けることができますkill。もちろん、kill一度に複数を使用することも、1つだけを使用することもできます。

$ kill %3 %4 %5
$ jobs
[3]   Terminated              sleep 20
[4]   Terminated              sleep 20
[5]-  Terminated              sleep 20
[6]+  Running                 sleep 20 &

PIDに接続された背景

プロセスを端末に接続することは、次のことを意味することもあります。これは私のシェルのPIDです。

$ echo $$
23543

他のシェルでは、straceプロセスを実行して接続して、どのシステムコールが実行されているかを確認します。

$ strace -p 23543
strace: Process 23543 attached
read(0,

メモ:readここでforコマンドを待っていることがわかります。これがターミナル/シェルの用途です。

ここでコマンドを入力し始め、lsシェルがこれをシステムコールの形でシェルにエコーするのを見ることができますwrite()

read(0, "l", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "l", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "s", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "s", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0,

これは、端末にプロセスを接続する別の形式です。

その他の形態

プロセスを端末に接続するためのより曖昧な参照の1つをここでも仮定できます。このU&L Q&Aの質問は次のとおりです。分離したプロセスに端末を接続するには?このコンテンツのすべての形式が含まれています。

この形式の引用の基本的な前提は、バックグラウンドタスクを完了し、現在のシェルでそのタスクを「切断」したことです。または、コマンドを使用してnohupこれを実行できますdisown

プロセスが拒否された場合、これ以上jobsコマンドfgbg使用して操作を実行することはできません。現在、シェルのPIDに関連付けられていません。

reptyr以前に拒否されたプロセスを再取得する従来の方法は、PIDを既存のシェルに再接続するなどのツールを使用することです。たとえば、私たちが2つの仕事を始め、それが次のようになったとしましょうnohup

$ nohup sleep 200 &
[1] 19720
$ nohup sleep 200 &
[2] 19721

それでも端末のジョブキューに接続されていますdisown。次のようにしましょう。

$ jobs
[1]-  Running                 nohup sleep 200 &
[2]+  Running                 nohup sleep 200 &
$ disown -a

今彼らは消えました:

$ jobs
$

これらはまだ元のシェルPID(23543)の子としてリストされています。

$ ps -eaf|grep -E "19720|19721"
vagrant  19720 23543  0 18:29 pts/1    00:00:00 sleep 200
vagrant  19721 23543  0 18:29 pts/1    00:00:00 sleep 200

ログアウトしてから再度ログインすると、これらのプロセスがデフォルトのPID 1の親としてリストされていることがわかります。

$ ps -eaf|grep -E "19720|19721"
vagrant  19720     1  0 18:29 ?        00:00:00 sleep 200
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200

nohupこれらのプロセスは、私たちが編集して編集するので、これを行うことができますdisown。そのうちの1つを再接続してみましょう。

$ reptyr -s 19720
[-] Timed out waiting for child stop.

^C

メモ:上記では、PID 19720をシェルに再接続してからCtrl+で終了しますC。今は消えたことがわかります。

$ ps -eaf|grep -E "19720|19721"
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200

関連情報