Linux 多工處理(暫停和恢復當前任務)

筆者平時使用 Linux 的場景絕大多數都是只有指令視窗,沒有圖形化介面可以操作。 但是只有一個指令視窗又很不方便,不能同時執行多個任務,遇到需要花一點時間執行的指令又只能乾等,一定有什麼方法可以解決,只是我不會...,經過一番研究後,然後又過了幾年,現在把當初學到的知識、技巧寫下來

暫停當前任務

假設在 linux 中要進入到 MySQL 指令介面(command-line client),使用指令登入(其實筆者使用的是 MariaDB):
    
mysql -uroot -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7765
Server version: 10.7.8-MariaDB-1:10.7.8+maria~ubu2004 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>
    

資料庫查詢到一半有其他指令要先執行,平時我們就需要使用 exit 指令直接退出資料庫指令介面,執行完後再重新登入一次,太麻煩了!
不過我們可以使用組合鍵 Ctrl + z 將資料庫指令介面暫停並退到背景中,這時候會出現以下資訊:
    
[1]+  Stopped                 mysql -uroot -p
    

代表我們將 mysql -uroot -p 這個指令放到背景,任務編號為 1 ,此指令目前已經暫停。
這時候我們就可以下指令處理其他事情了。

查看背景中的任務

剛剛使用 Ctrl + z 暫停任務的時候有顯示任務資訊,該任務編號是 1 ,如果忘記了也可以使用下面的指令查看當前在背景中的任務
    
jobs
    

輸出結果應該和剛剛的一樣,筆者在這裡多加上幾個任務,介紹一下其他顯示資訊:
    
jobs
[1]+  Stopped                 mariadb -uroot -p
[2]   Exit 100                sudo apt-get update
[3]-  Running                 ping 8.8.8.8 > /dev/null 2>&1 &
    

前面中括號內的數字代表的是任務編號,後面有「+」號(1號任務)的是當前任務(current job),有「-」號(3號任務)的是下一個任務(next job),其他的任務就沒有符號了。以上面的例子來說 1 號任務應該有被叫回前景執行後再被壓回背景,然後就執行這個 jobs 指令,所以可以看到 1 號任務是「當前任務」。
使用 Ctrl + z 將任務壓到背景後會暫停,所以會顯示 Stopped ,如果 Running 就代表正在背景持續執行, Exit 則代表任務已經執行完畢,正要自動退出,再次執行 jobs 應該就不會再看到他了。 如果要關閉任務可以直接使用(請自行替換任務編號):
    
kill %1
    

接續執行背景中的任務

只要知道任務編號後就可以使用下面的指令將任務放回到當前繼續執行(記得替換任務序號):
    
fg %1
    

在背景中繼續執行任務

當我們使用 Ctrl + z 把任務放到背景後,預設任務是「暫停」的,不會繼續執行,我們可以使用下面的指令把指定任務序號的任務讓他在背景中繼續執行:
    
bg %1
    

只是這樣執行的任務如果會輸出字串,就會直接彈在當前指令視窗上,雖然不影響功能,但是會很雜亂。

使用 bg 後他就不存在於 jobs 中了,筆者目前關閉這些任務的方式都是使用下面的指令找到處理程序的 PID:
    
ps -au
    

假設找出來的 PID 是 123 ,再使用 kill 刪除:
    
kill 123
    

在背景中執行任務

在執行指令時可以直接在最後面加上一個「&」符號,使其直接在背景中執行,例如:
    
ping 8.8.8.8 &
    

但是和上面的背景執行一樣,指令執行產生的輸出會瘋狂顯示在畫面中,

有個方法可以解決這個問題,指令後面的參數 > /dev/null 代表將訊息寫入到一個系統中專門用於接收輸入的地方,後面的 2>&1 則是讓錯誤訊息也使用和一般訊息同樣的輸出方式,最後的 & 則是使其在背景執行:
    
ping 8.8.8.8 > /dev/null 2>&1 &
    

這樣執行的指令就不會顯示訊息,在背景中持續執行不會影響到前台指令,但是任何錯誤訊息都不會顯示,請視需求使用。

留言