Terminal

將程序附加到終端意味著什麼?

  • August 9, 2018

我正在學習Linux。想到可以將程序附加到終端。將程序附加到終端 (TTY) 是什麼意思,我為什麼要這樣做?

注意: 對於 Unix 中的作業控制的一個很好的入門,我會引導你到關於主題的 Wikipedia 頁面 - Job control (Unix)


附加終端?

“附加到終端”這個片語通常是您在 shell 上下文中談論工作時會聽到的。但它確實有其他含義。片語“將程序附加到終端”也可以表示使用工具,例如gdbstracelsof附加到特定程序 ID (PID) 並列出資訊或監視它。

我將討論兩者,但首先,我將介紹工作隊列,因為我懷疑這就是你要找的那個。

背景 - 作業隊列

在類 Unix 作業系統中,您通常會看到作業的概念。在我使用過的大多數類 Unix 作業系統中,它們通常都以類似的方式工作。也就是說,它們可以在隊列(作業隊列)中被後台處理並分配一個編號,並且可以根據它們在此作業隊列中的編號的上下文對它們進行操作。

要將某些內容放入作業隊列,他們通常將此行為稱為後台處理。當您恢復已被後台處理的工作時,您將其稱為前台處理。執行此操作的命令是bg並且fg通常是。&您還可以在執行的任何命令的末尾使用 & 符號立即將作業放入後台。

例子

工作

$ sleep 2 &
[1] 19189

在這裡,我正在執行一個睡眠命令 2 秒並將其置於後台。輸出會立即為您提供有用的資訊,例如作業隊列號 ( [1]) 和後台作業的程序 ID 19189。

當此作業最終終止時,它將在其執行的終端中列印此類消息:

$
[1]+  Done                    sleep 2

前景與背景

對有背景的工作採取行動:

$ sleep 20 &
[1] 19207

$ fg
sleep 20
^C

在這裡,我已將作業發送到後台 ( &),然後將其帶回前台 ( fg),然後使用Ctrl+ C( ^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多個,或者只使用一個:

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

背景附加到 PID

將程序附加到終端也可能意味著以下內容。這是我的 shell 的 PID:

$ echo $$
23543

在另一個 shell 中,我正在執行strace並連接到該程序以查看它正在執行的系統呼叫:

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

**注意:**在這裡您可以看到它正在等待readfor 命令。這就是終端/外殼的作用。

在這裡我們可以看到我已經開始在其中鍵入命令,並且 shell 正在以系統呼叫ls的形式將這個回退回顯給 shell 。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,

這是將程序附加到終端的另一種形式。

其他形式

這裡也可以假設將程序附加到終端的更晦澀的參考之一。此 U&L Q&A 標題為:如何將終端附加到分離的程序?涵蓋所有形式的那個。

這種引用形式的基本前提是,您已經從事了一項後台工作,並將其與目前外殼“斷開”。您可以使用命令nohupdisown.

一旦程序被拒絕,您就不能再使用jobsfgbg命令對其進行操作。它不再與您目前 shell 的 PID 相關聯。

重新獲取以前不屬於的程序的傳統方法是使用諸如 之類的工具reptyr,它將重新附加一個 PID 到您現有的 shell。例如,假設我們開始了 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
$

它們仍然被列為我們原始 shell 的 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編輯。讓我們重新附加其中一個:

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

^C

**注意:**在上面,我將 PID 19720 重新附加到我的 shell,然後通過Ctrl+殺死它C。我們可以看到它現在消失了:

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

引用自:https://unix.stackexchange.com/questions/392577