掌握鏈接各個命令之間的鏈接符號用法也是很重要的。實際上,命令的用法並不難,例如 mkdir、touch和 find 也分別能夠簡單歸納爲「創建新目錄」、「更新文件」和「在目錄樹中查找文件」而已。html
但若是要理解linux
mkdir test_dir 2>/dev/null || touch images.txt && find . -iname "*jpg" > backup/dir/images.txt &
這一串命令的目的,以及爲何要這樣寫,就沒有這麼簡單了。工具
關鍵之處就在於命令之間的鏈接符號。掌握了這些符號的用法,不只可讓你更好理解總體的工做原理,還可讓你知道如何將不一樣的命令有效地結合起來,提升工做效率。命令行
在這一篇文章和接下來的文章中,我會介紹如何使用 & 號和管道符號(|)在不一樣場景下的使用方法。htm
幕後工做遞歸
我來舉一個簡單的例子,看看如何使用 & 號將下面這個命令放到後臺運行:進程
cp -R original/dir/ backup/dir/
這個命令的目的是將 original/dir/ 的內容遞歸地複製到 backup/dir/ 中。雖然看起來很簡單,可是若是原目錄裏面的文件太大,在執行過程當中終端就會一直被卡住。資源
因此,能夠在命令的末尾加上一個 & 號,將這個任務放到後臺去執行:字符串
cp -R original/dir/ backup/dir/ &
任務被放到後臺執行以後,就能夠當即繼續在同一個終端上工做了,甚相當閉終端也不影響這個任務的正常執行。須要注意的是,若是要求這個任務輸出內容到標準輸出中(例如 echo 或 ls),即便使用了 &,也會等待這些輸出任務在前臺運行完畢。get
當使用 & 將一個進程放置到後臺運行的時候,Bash 會提示這個進程的進程 ID。在 Linux 系統中運行的每個進程都有一個惟一的進程 ID,你可使用進程 ID 來暫停、恢復或者終止對應的進程,所以進程 ID 是很是重要的。
這個時候,只要你還停留在啓動進程的終端當中,就可使用如下幾個命令來對管理後臺進程:
jobs 命令能夠顯示當前終端正在運行的進程,包括前臺運行和後臺運行的進程。它對每一個正在執行中的進程任務分配了一個序號(這個序號不是進程 ID),可使用這些序號來引用各個進程任務。
$ jobs[1]- Running cp -i -R original/dir/* backup/dir/ &[2]+ Running find . -iname "*jpg" > backup/dir/images.txt &
fg 命令能夠將後臺運行的進程任務放到前臺運行,這樣能夠比較方便地進行交互。根據 jobs 命令提供的進程任務序號,再在前面加上 % 符號,就能夠把相應的進程任務放到前臺運行。
$ fg %1 # 將上面序號爲 1 的 cp 任務放到前臺運行 cp -i -R original/dir/* backup/dir/
若是這個進程任務是暫停狀態,fg 命令會將它啓動起來。
使用 ctrl+z 組合鍵能夠將前臺運行的任務暫停,僅僅是暫停,而不是將任務終止。當使用 fg 或者 bg 命令將任務從新啓動起來的時候,任務會從被暫停的位置開始執行。但 sleep 命令是一個特例,sleep 任務被暫停的時間會計算在 sleep 時間以內。由於 sleep 命令依據的是系統時鐘的時間,而不是實際運行的時間。也就是說,若是運行了 sleep 30,而後將任務暫停 30 秒以上,那麼任務恢復執行的時候會當即終止並退出。
bg 命令會將任務放置到後臺執行,若是任務是暫停狀態,也會被啓動起來。
$ bg %1 [1]+ cp -i -R original/dir/* backup/dir/ &
如上所述,以上幾個命令只能在同一個終端裏才能使用。若是啓動進程任務的終端被關閉了,或者切換到了另外一個終端,以上幾個命令就沒法使用了。
若是要在另外一個終端管理後臺進程,就須要其它工具了。例如可使用 kill 命令從另外一個終端終止某個進程:
kill -s STOP <PID>
這裏的 PID 就是使用 & 將進程放到後臺時 Bash 顯示的那個進程 ID。若是你當時沒有把進程 ID 記錄下來,也可使用 ps 命令(表明 process)來獲取全部正在運行的進程的進程 ID,就像這樣:
ps | grep cp
執行之後會顯示出包含 cp 字符串的全部進程,例如上面例子中的 cp 進程。同時還會顯示出對應的進程 ID:
$ ps | grep cp 14444 pts/3 00:00:13 cp
在這個例子中,進程 ID 是 14444,所以可使用如下命令來暫停這個後臺進程:
kill -s STOP 14444 注意,這裏的 STOP 等同於前面提到的 ctrl+z 組合鍵的效果,也就是僅僅把進程暫停掉。
若是想要把暫停了的進程啓動起來,能夠對進程發出 CONT 信號:
kill -s CONT 14444 這個給出一個能夠向進程發出的經常使用信號列表。若是想要終止一個進程,能夠發送 TERM 信號:
kill -s TERM 14444 若是進程不響應 TERM 信號並拒絕退出,還能夠發送 KILL 信號強制終止進程:
kill -s KILL 14444 強制終止進程可能會有必定的風險,但若是遇到進程無節制消耗資源的狀況,這樣的信號仍是可以派上用場的。
另外,若是你不肯定進程 ID 是否正確,能夠在 ps 命令中加上 x 參數:
$ ps x| grep cp 14444 pts/3 D 0:14 cp -i -R original/dir/Hols_2014.mp4 original/dir/Hols_2015.mp4 original/dir/Hols_2016.mp4 original/dir/Hols_2017.mp4 original/dir/Hols_2018.mp4 backup/dir/
這樣就能夠看到是否是你須要的進程 ID 了。
最後介紹一個將 ps 和 grep 結合到一塊兒的命令:
$ pgrep cp 8 18 19 26 33 40 47 54 61 72 88 96 136 339 6680 13735 14444
pgrep 能夠直接將帶有字符串 cp 的進程的進程 ID 顯示出來。
能夠加上一些參數讓它的輸出更清晰:
$ pgrep -lx cp 14444 cp
在這裏,-l 參數會讓 pgrep 將進程的名稱顯示出來,-x 參數則是讓 pgrep 徹底匹配 cp 這個命令。若是還想了解這個命令的更多細節,能夠嘗試運行 pgrep -ax。
總結
在命令的末尾加上 & 可讓咱們理解前臺進程和後臺進程的概念,以及如何管理這些進程。
在 UNIX/Linux 術語中,在後臺運行的進程被稱爲守護進程daemon。若是你曾經據說過這個詞,那你如今應該知道它的意義了。
和其它符號同樣,& 在命令行中還有不少別的用法。在下一篇文章中,我會更詳細地介紹。