將程序附加到終端意味著什麼?
我正在學習Linux。想到可以將程序附加到終端。將程序附加到終端 (TTY) 是什麼意思,我為什麼要這樣做?
注意: 對於 Unix 中的作業控制的一個很好的入門,我會引導你到關於主題的 Wikipedia 頁面 - Job control (Unix)。
附加終端?
“附加到終端”這個片語通常是您在 shell 上下文中談論工作時會聽到的。但它確實有其他含義。片語“將程序附加到終端”也可以表示使用工具,例如
gdb
或strace
或lsof
附加到特定程序 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,
**注意:**在這裡您可以看到它正在等待
read
for 命令。這就是終端/外殼的作用。在這裡我們可以看到我已經開始在其中鍵入命令,並且 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 標題為:如何將終端附加到分離的程序?涵蓋所有形式的那個。
這種引用形式的基本前提是,您已經從事了一項後台工作,並將其與目前外殼“斷開”。您可以使用命令
nohup
或disown
.一旦程序被拒絕,您就不能再使用
jobs
、fg
或bg
命令對其進行操作。它不再與您目前 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