Linux 從 0 到 1(三) - 數據處理,管道,重定向,監視系統活動,后臺運行及合并多個終端

數據處理

grep命令:篩選數據

grep是Globally search a Regular Expression and Print的縮寫,意思是《全局搜索一個正則表達式,并且打印》。

grep命令的功能簡單說來是在文件中查找關鍵字,并且顯示關鍵字所在的行。

grep命令極為強大,也是Linux中使用最多的命令之一。它的強大之處在于它不僅可以實現簡單的查找,而且可以配合《正則表達式》來實現比較復雜的查找。

grep的簡單用法

grep的使用方法有很多種。但我們一開始先學習最基本的用法:

grep text file

可以看到,上面就是grep命令的最基本用法。

text代表要搜索的文本,file代表供搜索的文件。

我們用實際的例子來學習。比如我要在用戶的家目錄的 .bashrc 文件中搜索alias這個文本,而且顯示所有包含alias的行。

grep alias .bashrc

grep命令列出了.bashrc文件中所有包含alias的行,并且在小編的終端中,以紅色標出了每一個alias。其實grep更像是一個過濾器,它可以篩選出我們要找的對象。

如果我們要用grep命令在一個文件中查找用空格隔開的文本,那么就要加上雙引號,例如:

grep "Hello World" file2
常用參數
  • -i參數:忽略大小寫,i是英語ignore的縮寫,表示“忽略”。
grep -i alias .bashrc
  • -n參數:顯示行號,n是英語number的縮寫,表示“數字,編號”。
grep -n alias .bashrc
  • -v參數:只顯示文本不在的行,v是invert的縮寫,表示“顛倒,倒置”。-v參數的作用與正常grep的作用正好顛倒,就是只顯示搜索的文本不在的那些行。
grep -v alias .bashrc
  • -r參數:在所有子目錄和子文件中查找,r是英語recursive的縮寫,表示“遞歸”。
    如果用了-r參數,那么grep命令使用時的最后一個參數(grep text file這個模式中的file)需要換成directory,也就是必須是一個目錄。因為-r參數是讓grep命令能夠在指定目錄的所有子目錄和子文件中查找文本。
grep -r "Hello World" folder/

表示在folder這個目錄的所有子目錄和子文件中查找Hello World這個文本。當然了,以上例子中,folder后面的斜杠(/)不是必須的,這里只是為了清楚表明folder是一個目錄。只要folder是一個目錄,Linux系統是不會搞錯的。

Linux中還有一個rgrep的命令,它的作用相當于grep -r

grep 的高級用法:配合正則表達式

我們首先來看一眼以下的這個表格,表格中列出了最常用的一些正則表達式的字符以及其含義:

特殊字符 含義
. 匹配除 "\n" 之外的任何單個字符
^ 行首(匹配輸入字符串的開始位置)
$ 行尾(匹配輸入字符串的結束位置)
[] 在中括號中的任意一個字符
? 問號前面的元素出現零次或一次
* 星號前面的元素可能出現零次,一次或多次
+ 加號前面的元素必須出現一次以上(包含一次)
一根豎線 邏輯或
() 表達式的分組(表示范圍和優先度)

首先,為了讓grep命令知道我們要使用正則表達式,須要加上-E參數。例如:

grep -E Alias .bashrc

當然了,Linux也有一個命令egrep,其效果等同grep -E

不要懷疑,Alias也算是一個正則表達式,只不過沒有用到上面表格中的特殊符號而已。
首先來看這個例子:

grep -E ^alias .bashrc

這個例子中,我們用到了這個特殊符號,上面的表格里對于已經做了說明:行首(匹配輸入字符串的開始位置)。也就是說,^后面的字符須要出現在一行的開始。

因此,就搜出了如上圖中的三行,這三行都是包含alias,并且以alias開頭的。

再來舉幾個例子:

grep -E [Aa]lias .bashrc

再比如:

grep -E [0-4] .bashrc

用于搜索包含0至4的任一數字的行。

grep -E [a-zA-Z] .bashrc

用于搜索包含在a至z之間的任意字母或者A至Z之間的任意字母的行。

其實在Ubuntu這樣的Linux發行版中,grep如果要和正則表達式配合,不加-E參數也是可以的,正則表達式始終是激活的。不過有的Unix發行版的系統可能不加-E參數就不能搜索正則表達式,因此為了兼容,我們一般時候會說加上-E參數比較好。

sort命令:為文件排序

為了演示,我們首先用文本編輯器(可以用nano)來創建一個文件,名叫name.txt比如,然后在里面寫入以下的行:

John
Paul
Luc
Matthew
Mark
jude
Daniel
Samuel
Job

然后進行 sort:

sort name.txt

sort命令將name.txt文件中的行按照首字母的英文字典順序進行了排列,而且sort命令并不區分大小寫。

-o參數:將排序后的內容寫入新文件

如果你打開name.txt文件,你會發現,經過了sort命令的“洗禮”,name.txt中的內容還是維持原來的順序。

單獨使用sort命令是不會真正改變文件內容的,只是把排序結果顯示在終端上。

那我們要存儲排序結果到新的文件怎么辦呢?可以用-o參數。

sort -o name_sorted.txt name.txt

可以看到,name.txt經過sort命令排序之后的內容被儲存在了新的文件name_sorted.txt中,而name.txt的內容是不變的。

-r參數:倒序排列

-r參數中的r是reverse的縮寫,是“相反,反面”的意思,與普通的僅用sort命令正好相反。

sort -r name.txt
-R參數:隨機排序

-R參數比較“無厘頭”,因為它會讓sort命令的排序變為隨機,就是任意排序,也許每次都不一樣。但在有些時候,還是很有用的。

sort -R name.txt
-n參數:對數字排序

對數字的排序有點特殊。默認地,僅用sort命令的時候,是不區分首字符是否是數字的,因此還是按照1-9的順序來排序。例如138會排在25前面,因為1排在2的前面。

那如果我們要sort命令識別整個數字,比如按照大小順序來說,25應該排在138前面,那該怎么辦呢?

就可以請出我們的-n參數了。n是number的縮寫。是英語“數字”的意思。-n參數用于對數字進行排序,按從小到大排序。

wc命令:文件的統計

wc是word count的縮寫,因此,wc命令貌似是用來統計單詞數目的,但其實wc的功能不僅止于此。wc命令還可以用來統計行數,字符數,字節數等。

跟前面的命令一樣,wc命令的用法也是后接文件名。wc命令很有用,應該會成為你經常用到的命令之一。

wc name.txt

如果不加選項參數,那么wc命令的返回值有些特殊,有點晦澀難懂。

可以看到返回值是

9 9 50 name.txt

那么這三個數字:9,9,和50分別表示什么呢?

這三個數字,按順序,分別表示:

  • 行數

  • 單詞數

  • 字節數

因為我們之前創建name.txt時,每一行只有一個單詞(英語名字),所以這里統計的行數和單詞數都是9。

-l參數:統計行數

為了只統計行數,我們可以加上-l參數。l是英語line的縮寫,表示“行”。

-w參數:統計單詞數

w是英語word的縮寫,word是英語“單詞”的意思。因此-w參數用于統計單詞。

-c參數:統計字節數

不知道為什么是c,因為byte或者octet(都可以表示《字節》)的首字母都不是c啊。不管了。也許c是character(英語“字符”的意思)的縮寫吧。

-m參數:統計字符數

不知道為什么是m,因為character(英語“字符”)的首字母不是m啊。不管了。

uniq命令:刪除文件中的重復內容

有時候,文件中包含重復的行。我們也許想要將重復的內容刪除。

這時,uniq命令就顯得很有用了。uniq是英語unique的縮寫,表示“獨一無二的”。

為了演示,我們創建一個文件repeat.txt(repeat是英語“重復”的意思),里面寫入如下排序好的內容(因為uniq命令還是有點“呆”,因為它只能將連續的重復行變為一行):

Albert
China
France
France
France
John
Matthew
Matthew
patrick
Steve
Vincent

可以看到,有三個France連在一起,兩個Matthew連在一起。

我們用uniq命令來處理看看:

uniq repeat.txt

最后結果是,三個連續的France只剩下一個了,兩個連續的Matthew也只剩一個了。

但是uniq命令并不會改變原文件的內容,只會把處理后的內容顯示出來。如果想將處理后的內容儲存到一個新文件中,可以使用如下的方法:

uniq repeat.txt unique.txt
-c參數:統計重復的行數

-c參數用于顯示重復的行數,如果是獨一無二的行,那么數目就是1。

-d參數:只顯示重復行的值
cut命令:剪切文件的一部分內容

cut命令用于對文件的每一行進行剪切處理。

-c參數:根據字符數來剪切

比如,我們要name.txt的每一行只保留第2至第4個字符。可以這樣做:

cut -c 2-4 name.txt

流、管道、重定向

命令的輸出可以有三個去向:

  • 終端

  • 文件

  • 其他命令的輸入

到目前為止,我們只用過第一種形式:把命令的輸出結果顯示在終端。

>和>>:重定向到文件

我們先從最簡單的開始。最簡單的操作就是把命令的輸出結果重定向到文件中,就不會在終端顯示命令運行結果了。

在創建文件之前,我們來談談cut命令的進階用法。

cut命令進階:根據分隔符來剪切

首先,我們來看一種特殊的文件形式:CSV格式。

CSV是Comma Separated Values的縮寫,翻成中文是《逗號分隔值》。

以下摘自百度百科:
逗號分隔值(Comma-Separated Values,CSV,有時也稱為字符分隔值,因為分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。
純文本意味著該文件是一個字符序列,不含必須像二進制數字那樣被解讀的數據。
CSV文件由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字符或字符串,最常見的是逗號或制表符。
通常,所有記錄都有完全相同的字段序列。

CSV文件的后綴名是.csv,通常可以被Excel等軟件打開,打開之后會把分隔符隔開的各個數值填充到表格里。

我們來構建一個CSV文件。因為我們要用逗號作為分隔符,來學習cut命令的進階使用:根據分隔符來剪切。

我們的CSV文件的內容可以如下,我們用Nano這樣的文本編輯器來編寫這個CSV文件,并且取名:notes.csv

Mack,95 / 100,很不錯
Matthew,30 / 100,跟平時一樣水
Louise,70 / 100,有進步
Luke,54 / 100,接近平均分了
John,68 / 100,不錯,但還可以更好
Samuel,100 / 100,總是那么完美
David,40 / 100,退步挺大呀

如上圖所示,我們的notes.csv文件中每一行由三部分組成,每部分由一個逗號分隔:

  • 學生名字

  • 成績(滿分是100分)

  • 評語

現在假如我們要從notes.csv文件中提取名字那一列,怎么辦呢?我們不能用cut命令的-c參數啊,畢竟每個名字的字符數不相等。

我們看到文件中每一行的每一部分是用分隔符來隔開的,所以我們可以這樣做:

需要用到兩個參數:

  • -d參數:d是delimiter的縮寫,是英語《分隔符》的意思。用于指定用什么分隔符(比如逗號,分號,雙引號等等)。

  • -f參數:f是field的縮寫,是英語《區域》的意思。表示剪切下用分隔符分隔的哪一塊或哪幾塊區域。

我們的notes.csv文件是用逗號來分隔三個部分的,我們要剪切下來的是名字那一列,也就是第一部分。因此我們可以這樣使用:

cut -d , -f 1 notes.csv

那如果我們只想剪切下評語部分呢?評語是第三部分:

cut -d , -f 3 notes.csv

那如果我們要第一和第三部分呢?可以這樣:

cut -d , -f 1,3 notes.csv

同樣地,我們可以用

cut -d , -f 2- notes.csv 

來剪切第二部分直到最后的內容。

好了,現在準備工作做好了,我們可以來學習重定向流符號了。

>:重定向到新的文件
我們知道雖然我們剛才用cut命令從notes.csv文件中剪切出來一些部分,但原始的notes.csv文件是不變的。

我們現在想要將剪切出來的部分儲存到一個文件中,而不是像之前那樣顯示在終端里。

(為了方便,我們在家目錄下新建一個redirect目錄,將之前的notes.csv文件放到這個目錄下,再用cd redirect命令定位到這個目錄)

這個符號可以將命令的輸出結果重定向到你自己選擇的文件中。例如:

cut -d , -f 1 notes.csv > students.txt

有時候,我們既不想將命令的輸出顯示在終端,又不想將其儲存到文件中,怎么辦呢?

Linux中有一個俗稱《黑洞》的文件,就是

/dev/null

/dev/null 文件是特殊文件,不是一個目錄。此文件具有唯一的屬性:它總是空的。它能使發送到/dev/null 的任何數據作廢,就好像這些數據掉進了無底的黑洞一般。

因此,假如我們不需要在終端顯示剛才那個cut命令的結果,也不想存儲到文件里,那么可以這么做:

cut -d , -f 1 notes.csv > /dev/null

>>: 重定向到文件末尾
我們已經知道,單獨一個>符號可以實現重定向到新的文件(覆蓋文件內容),那么兩個連在一起的>符號有什么作用呢?

>>的作用與>是類似的,不過它不會像>那么危險(如果文件已經存在,>符號會覆蓋文件內容),而是將重定向的內容寫入到文件末尾,起到追加的作用。如果文件不存在,也會被創建。

我們就來實踐一下:

cut -d , -f 1 notes.csv >> students.txt

因為我們上一個例子中已經用>符號來重定向名字那列的內容到students.txt文件中了,所以上面的命令會追加同樣內容到students.txt的末尾。

>>符號在很多情況下非常有用,比如你人不在電腦前,而你又想讓終端為你記錄程序運行的結果,就可以在一個日志文件的末尾一直寫入。例如:

command >> results.log
2>,2>>,2>&1:重定向錯誤輸出

我們首先來學點新知識。

stdin,stdout,stderr:標準輸入,標準輸出,標準錯誤輸出

對于我們的終端命令行,我們從鍵盤向終端輸入數據,這是標準輸入,也就是stdin。

終端接收鍵盤輸入的命令,會產生兩種輸出:

  • 標準輸出:stdout。指終端輸出的信息(不包括錯誤信息)。

  • 標準錯誤輸出:stderr。指終端輸出的錯誤信息。

第一個stdout就是我們到目前為止看到的那些Linux命令的正常運行結果,比如在終端中運行ls命令,我們以前也看到了它列出當前目錄下所有文件。

這三個你也可以把它們看作流:

  • stdin:標準輸入流。英語standard input的縮寫(standart是英語“標準”的意思,input是英語“輸入”的意思)。標準輸入是指輸入至程序的數據(通常是文件)。程序要求以讀(read)操作來傳輸數據。并非所有程序都要求輸入。如dir或ls程序運行時不用任何輸入。 除非重定向,輸入是預期由鍵盤獲取的。 標準輸入的文件描述符為 0

  • stdout:標準輸出流。英語standard output的縮寫(output是英語“輸出”的意思)。標準輸出是指程序寫輸出數據的流。程序要求數據傳輸使用寫的運算。并非所有程序都要求輸出。如mv或ren程序在成功完成時是沒有輸出的。 除非重導向,輸出是預期顯示在終端上的。 標準輸出的文件描述符為 1 (一)。

  • stderr:標準錯誤輸出流。英語standard error的縮寫(error是英語“錯誤”的意思)。標準錯誤輸出是另一個輸出流,用于輸出錯誤消息或診斷。它獨立于標準輸出,且標準輸出和標準錯誤輸出可以分別被重定向。標準錯誤輸出的文件描述符為 2 (二);

文件描述符 名字 解釋
0 stdin 標準輸入
1 stdout 標準輸出
2 stderr 標準錯誤輸出

那什么是文件描述符呢?

文件描述符的英語是File Descriptor,簡稱fd。

文件描述符是一個用于表述指向文件的引用的抽象化概念。這定義本身也有點抽象。我們不需要太深入了解。大致只需要知道:

  • 文件描述符在形式上是一個非負整數。
  • 實際上,它是一個索引值,指向操作系統內核為每一個進程所維護的該進程打開文件的記錄表。
  • 當程序打開一個現有文件或者創建一個新文件時,內核向進程返回一個文件描述符。

文件描述符通常是Unix,Linux等系統的概念。在Windows中,也有類似的概念,但是Windows中稱為《句柄》,就是handle。

其實,>和>>符號只是將標準輸出重定向到文件,并不能將標準錯誤輸出重定向到文件。
那么我們要重定向標準錯誤輸出,該怎么辦呢?

我們就要用到 2> 這個符號
為什么是2呢?記得上面說的嗎?標準錯誤輸出的文件描述符是2,所以這里的2表示標準錯誤輸出。如果沒有2,單獨的>符號就是重定向標準輸出(文件描述符為1)。

cat not_exist_file.csv > results.txt 2> errors.log

這個命令里有兩個重定向:

>: results.txt:將標準輸出重定向到results.txt文件中。

2>: errors.log:將標準錯誤輸出重定向到errors.log文件中。

類似地,2>>符號用于將標準錯誤輸出重定向到文件末尾。

合并輸出
上面我們學習了如何將標準輸出和標準錯誤輸出分別重定向到不同文件。但是有的時候,我們比較“任性”,我們就想把標準輸出和標準錯誤輸出都重定向到同一個地方。怎么做呢?

須要使用 2>&1 這個組合符號。

看著怪怪的對吧?由四個字符組成。這個符號的作用是:將標準錯誤輸出重定向到與標準輸出相同的地方。

我們用實例演示一下:

cat not_exist_file.csv > results.txt 2>&1

上面的命令的作用是:將cat not_exist_file.csv這個命令的所有輸出(標準輸出和標準錯誤輸出)都重定向到results.txt文件中。

如上圖所示,運行cat not_exist_file.csv > results.txt 2>&1命令之后,因為not_exist_file.csv這個文件不存在,但又因為加了2>&1這個符號,所以標準輸出(為空)和標準錯誤輸出(cat: not_exist_file.csv: No such file or directory)都重定向到results.txt文件中了。

大家是否覺得要將標準輸出和標準錯誤輸出都重定向到文件末尾,應該是這樣寫:2>>&1 呢?

其實不然,這樣是不對的。我們還是保持2>&1這個組合不變,只改變前面的符號就行了。例如:

cat not_exist_file.csv >> results.txt 2>&1
<,<<:從文件或鍵盤讀取

到目前為止,這一課我們只講了如何重定向命令的輸出,也就是決定命令輸出的信息的去向。那么接著我們可以做一點相反的事情:決定命令的輸入來自哪里。

當然了,上面也說了,不是所有的命令都有輸入,也不是所有的命令都有輸出。

到目前為止,我們的命令的輸入都來自于后面接的參數,這些參數有些是文件名,有些是目錄名,等等。

但我們其實可以使命令的輸入來自于文件或者鍵盤輸入。如下圖所示:

<:從文件中讀取

我們用一個簡單的例子來演示:

cat < notes.csv

如上圖所示,cat < notes.csv的運行結果和cat notes.csv (不用重定向流符號)一模一樣,都是在終端打印notes.csv的內容,那我們為什么需要<符號呢?

事實上,雖然cat < notes.csv的運行結果和cat notes.csv一樣,但是原理卻不一樣:

  • cat notes.csv :這種情況下,cat命令接受的輸入是notes.csv這個文件名,那么它要先打開notes.csv文件,然后打印出文件內容。

  • cat < notes.csv :這種情況下,cat命令接受的輸入直接是notes.csv這個文件的內容,cat命令只負責將其內容打印。而打開文件并將文件內容傳遞給cat命令的工作則交給shell程序(也就是控制終端的程序)來完成。

所以,雖然結果看似一樣,但是中間的過程卻是不一樣的。

<<:從鍵盤讀取

<<符號的作用是將鍵盤的輸入重定向為某個命令的輸入,很多情況下都很有用。

我們用實例來說明:

sort -n << END

如上圖所示,輸入這條命令之后,回車,終端就進入了鍵盤輸入模式。

我們知道sort -n的作用是按照從小到大進行排列。那么我們就輸入一些數值吧(每輸一個數值,用回車鍵來換行,接著輸入下一個數值,輸入END來結束輸入,END被稱為結束字符串。當然了,你可以用其他字符串,比如haha,nihao,不一定要用END。



可以看到,sort -n命令將我們輸入的一串數值進行了由小到大的排序。

我們再試試其他命令與<<符號的配合,這次我們用wc命令吧,wc命令用于統計字符等,如果配合-m參數就是統計字符數。

wc -m << END

可以看到,《How many characters are there in this sentence ?》這句話中有49個字符。

當然了,我們也可以將之前學習的輸出重定向符號和這一節的輸入重定向符號結合使用:

sort -n << END > numbers_sorted.txt 2>&1

以上命令將sort -n命令對數值排序的結果都輸入到numbers_sorted.txt文件中,如果有錯誤信息也輸入。

|:管道

管道也算是重定向流的一種。

將兩個命令連成管道,這是什么意思呢?簡單的說就是將一個命令的輸出作為另一個命令的輸入。
大致來說:命令1的輸出立即會變成命令2的輸入。使用這個原理,我們可以用 | 符號連接無窮多個命令,構成很長的命令管道。

我們用幾個實例來學習管道吧。

按學生名字排序

你應該還記得我們的notes.csv文件,其中有三部分,用逗號隔開的,第一部分是學生名字,第二部分是成績,第三部分是評語。

之前我們用cut -d , -f 1 notes.csv命令來剪切了名字那一列。我們前一課學了sort命令,它用于排序文件內容。

那么為什么不把這兩個命令用管道符連接起來呢?我們可以用sort命令對cut命令提取到的名字列進行排序:

cut -d , -f 1 notes.csv | sort

如上圖所見,我們用sort命令對名字列按照首字母的字典順序進行了排序。

如果我們將上面的命令再擴充一下,配合之前學習的輸出重定向符號,就變成了這樣:

cut -d , -f 1 notes.csv | sort > sorted_names.txt

我們將sort命令排序的結果重定向到sorted_names.txt文件中了。

根據大小排序目錄

之前我們學過,du命令可以深入遍歷當前目錄下每個子目錄,把所有文件的大小都做一個統計。

我們可以用cd命令來回到我們的家目錄。然后運行du命令。

問題是:du命令要運行挺久的,因為小編家目錄下文件很多。

單獨用du命令的缺點我們也有目共睹了,一是可能要運行很久(如果文件很多),二是顯示結果沒有排序,雜亂無章。

但如果我們這樣做就會清爽很多:

du | sort -nr | head

還記得head命令的用法么?如果不用-n參數指定顯示行數,那么head會默認顯示前10行。

所以以上命令的作用是:

  • du :深入遍歷當前目錄下每個子目錄,把所有文件的大小都做一個統計。

  • sort -nr :sort命令的-n參數是按以數值來排序(此處是文件大小)排序,默認是小的在前;-r參數是倒序排列,有了-r參數,-n參數就變成大的數值在前了。

  • head :列出前十個數值(這里是文件大小)。

列出包含關鍵字的文件

還記得我們的好朋友grep命令嗎?之前有學過,這個命令很強大,可以在文件中查找關鍵字,并且顯示關鍵字所在的行。但有時,我們會覺得grep顯示的信息太冗長了。每一行不僅有文件名,還有關鍵字出現的那一行文本,等等。

我們可以運行以下命令試試:

sudo grep log -Ir /var/log | cut -d : -f 1 | sort | uniq

這個命令做了什么呢?讓我們一步步來分解:

  • sudo grep log -Ir /var/log:遍歷/var/log這個目錄及其子目錄,列出所有包含log這個關鍵字的行。-I參數用于排除二進制文件。-r參數用于遞歸遍歷。sudo命令是為了以root身份查找系統文件夾/var/log。

  • cut -d : -f 1從命令1的輸出結果中只剪切出文件名那一列(由冒號分隔的第一個區域)。

  • sort將文件名的列以首字母的字典順序進行排序。

  • uniq: 去掉重復的文件名。

監視系統活動

w命令:都有誰,在做什么?

第一個出場的命令是迄今為止我們遇到過的最短的命令,這個命令只有一個字母:w

就是這么一個很簡單的命令,卻挺實用,它可以幫助我們快速了解系統中目前有哪些用戶登錄著,以及他們在干什么。

如果你負責一臺Linux服務器,有時候它會過載,變得很慢,這時你可以登錄此服務器,然后運行w命令,快速了解到底發生了什么事。

如上圖所見,目前Linux系統中只有一個用戶登錄,就是小編自己的用戶,名叫oscar。

w命令輸出的信息雖然短,但是比較密集,看第一眼并不容易了解到底是什么。但其實w命令給出的信息非常有用。

我們將其分解成不同的部分來解釋,按照從上到下,從左到右的順序。

  • 時間(用date命令也可以做到)
    我們看到信息的第一行中有 17:36:13,這就是當前時間:17點36分13秒。
    我們之前學過date這個命令,它可以顯示當前日期,時間,和時區:

  • 運行時間(用uptime命令也可以做到)
    w命令的輸出中,緊跟在當前時間后面的是 up 25 min
    up是英語《運行正常的》的意思。min是英語minute的縮寫,表示《分鐘》。
    所以 up 25 min 表示系統已經運行了25分鐘了,就是從開機登錄到現在經過的時間。
    這個信息還是挺有用的,因為一旦系統重啟或關機,那么運行時間會重歸0。

  • 負載(同樣可以用uptime命令獲知)
    在w命令的輸出的第一行的右邊,有三個數值,表示負載:

load average: 0.15, 0.11, 0.09

負載是系統活動的一個指標:

這三個數值從左到右分別表示:

  • 1分鐘以內的平均負載(0.15)。

  • 5分鐘之內的平均負載(0.11)。

  • 15分鐘之內的平均負載(0.09)。

這些數值具體表示什么呢?

說起來稍微有點復雜。閱讀手冊,我們可以知道:這些數值表示一段時間內的平均活躍進程數(也就是使用CPU處理器的進程數。進程簡單地說就是運行起來的程序)。

由此可知,近1分鐘內平均有0.15個進程使用了處理器,也就是說處理器有15%的時間是活躍的。

負載的數值也取決于電腦的處理器的核心數目。一個單核的處理器如果負載超過了1,那就是過載了。雙核的處理器如果負載超過了2,那就是過載了。四核的處理器如果負載超過了4,那就是過載。依次類推。

有的服務器過載的時候負載的數值甚至能達到50那么多。

如果負載值在較長的時間中都維持比較大的話,就說明系統出問題了。我們可以用tload命令來繪制隨時間變化的負載《曲線》圖。

tload

tload命令的輸出(隨時間變化):

圖中橫坐標是時間,縱坐標的高低表示負載大小,左邊猛然上升的縱坐標值是因為小編打開了火狐瀏覽器。

  • 登錄的用戶列表(用who命令也可以做到)
    w命令的輸出中,除去第一行,下面的行可以歸為一個部分,就是登錄的用戶列表。
    這幾行信息顯示當下系統中連接的用戶是哪幾位,他們在做什么任務,任務進行多長時間了。
    可以看到,有兩行都是以oscar開頭,我目前是在自己的個人電腦上,所以Linux系統中只有我一個用戶登錄,那為什么有兩行oscar呢?我們先來了解下各列的意義,就會明白了。
  • USER:用戶名(登錄名)。

  • TTY:Linux中默認提供了六個命令行終端和一個圖形終端:tty1tty7。其中tty1tty6是命令行終端
    Ubuntu中可以通過Ctrl+Alt+F1~F7切換這7個終端。除了這7個基本的《大環境》終端,我們還可以在tty7中開很多不是全屏的終端,也就是我們平時用來輸入命令行的圖形終端(ctrl + shift + T快捷鍵),這些終端的名字是以pts開頭的。pts是 pseudo terminal slave的縮寫,表示“偽終端從屬”。如果我新開一個圖形終端,那么顯示名稱為pts/0,如上圖中所示。如果我再開一個圖形終端,那么它的名字就是pts/1。依次類推。

  • LOGIN@:用戶連接系統的時間。

  • IDLE:用戶有多久沒活躍了(沒運行任何命令)。idle是英語“不活躍的”的意思。

  • WHAT:當下用戶正運行的程序。what是英語“什么”的意思。

在小編的情況,我們看到有兩個用戶,有兩個oscar。第一個oscar對應的是登錄Ubuntu系統的用戶,也就是我們開機后登錄的用戶,進入的是Ubuntu的圖形用戶界面,可以從WHAT那列的信息看出來,這里是gnome-sessi,是gnome session(session是英語“會話”的意思)的縮寫,表示Gnome這個桌面系統。第二個oscar對應的是打開當前我們正在操作的這個圖形終端的用戶,也是oscar,不過TTY那列是pts/0,WHAT那列是w,說明用戶運行了w命令。沒錯啊,因為這些信息就是w命令運行的輸出結果。

w命令雖然很有用,但是給出的信息還是不夠詳盡。我們下面來看看如何獲得詳細的系統進程的信息。

ps命令和top命令:列出運行的進程

簡單說來,進程就是加載到內存中運行的程序。

大多數程序運行時都只在內存中啟動一個進程。例如Linux中的OpenOffice這個軟件。有的程序運行時卻會創建不少進程,例如Google的Chrome瀏覽器,每開一個標簽欄都會創建一個新的進程。

在網絡服務器上,一般我們都是用Apache這個軟件來發送網頁給網民。Apache在運行時就會創建很多進程,分別負責不同的任務。一般的數據庫軟件,例如MySQL,PostgreSQL也是如此。因此,假如你發現一個程序創建了好多個進程的話,并沒有什么好吃驚的。

在Linux中,我們有兩個命令可以幫助我們查看系統中運行的進程。

ps 是Process Status的縮寫,所以ps命令用于顯示當前系統中的進程。

ps命令顯示的進程列表不會隨時間而更新,是靜態的,只是運行ps命令當時的那個狀態,或者說是一個進程的快照,英語稱為snapshot,就好像照了一張照片一樣。

我們試著不加任何參數直接運行ps命令:

可以看到顯示結果有四列:

  • PID:進程號。pid是process identifier的縮寫。每個進程有唯一的進程號。之后我們學習如何結束進程時需要用到進程號。

  • TTY:進程運行所在的終端。

  • TIME:進程運行了多久。

  • CMD:產生這個進程的程序名。如果你在進程列表中看到有好幾行都是同樣的程序名,那么就是同樣的程序產生了不止一個進程(例如MySQL程序)。

在小編的情況,我們運行ps命令時顯示了兩個進程正在運行,一個是bash,也就是操控當前終端的shell程序。另一個是ps命令自己。

兩個進程,這就是全部了?

當然不是。ps命令不帶參數使用時只會列出當前運行ps命令的用戶在當前這個終端中所運行的進程。有好多進程是root用戶運行的,就沒列出來。還有的進程,雖然也是當前用戶運行的,但不是在當前的終端里,所以也沒列出來。

ps命令有很多不同的參數。你可以用man ps來查看。可不要被眾多的選項參數嚇到。

我們不可能介紹每個參數,下面就介紹一些常用的參數吧。

-ef:列出所有進程

-ef參數可以使ps命令列出所有用戶在所有終端的所有進程。

ps -ef

可以看到,用了-ef參數,因為列出所有用戶的所有進程,所以比剛才不加參數的ps命令多了一些列。

例如第一列UID,是user identifier的縮寫,表示《用戶名》,也就是運行進程的用戶。

-efH:以喬木狀列出所有進程
ps -efH

比上面的-ef多加了一個H參數,可以使ps命令按照喬木狀列出進程。有的進程是某些進程的子進程。

比如上圖中,我們可以看到/sbin/init這個程序(進程)就啟動了其他的進程,比如udevd --daemon,portmap,smbd -F,等等。

ps -u 用戶名:列出此用戶運行的進程。

可以看到有不少進程,單獨用ps的時候只有兩個進程,那是因為有好多進程不是在pts/0那個終端里運行的。

top:進程的動態列表

ps命令雖然強大,但有一個缺陷:是靜態的,只能記錄當下那一刻的進程列表。

但事實上,我們的系統是時刻變化的。有些進程這一秒在運行,下一秒可能就被終止了。所以ps命令并不能幫助我們實時監控系統的進程。

怎么才能獲取一個隨時間一直在變的進程列表呢?就需要用到top命令了。

這個列表是交互性的,而且實時更新。

第一行,你可以看到當前時間(04:02:41,就是凌晨4點02分41秒),系統運行時間(3:52,也就是3個小時52分鐘),用戶數目(2 users,就是“兩個用戶”),平均負載(load average: 0.50, 0.34, 0.25)。

接下來的幾行,我們不過多解釋了,因為這涉及到操作系統的一些概念。

在下面,PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,COMMAND開始的那個列表就是進程列表了。

但為什么相比之前ps -ef時進程少了這么多呢?

因為top命令無法顯示全部的進程。它只顯示排在前面的一些進程,為了整個信息區域正好占據終端中一個頁面的大小。

默認地,這些進程是按照使用處理器的比率來排序的,從大到小(按照%CPU那一列的數值),最消耗處理器的進程排在最前面。所以如果你覺得自己的系統變慢了,過載了,查看列表中最開始的幾個進程是個好主意。

前面說過了,top命令輸出的信息頁面不但是動態變化的,而且是可交互的。

我們用一些鍵盤的按鍵可以控制top的顯示結果。

q:退出top

h:顯示幫助文檔,也就是哪些按鍵可以使用。按下任意鍵返回。

B:大寫的B,加粗某些信息。

f:在進程列表中添加或刪除某些列。

F:改變進程列表排序所參照的列。默認情況下,是按照%CPU那一列來排序。

u:依照用戶來過濾顯示。可以輸入用戶名,按回車。

k:結束某個進程。會讓你輸入要結束的進程的PID。

s:改變刷新頁面的時間。默認地,頁面每隔3秒刷新一次。

當然了,Linux下有很多優秀的軟件,做得比top和ps更好,例如:Linux中比Top顏值更高的系統監控工具Glances。

Ctrl + C和kill命令:停止進程

有時候,系統會卡住。這在Linux中也是會發生的。

在Linux中停止進程有幾種方法:

  • Ctrl + C:停止終端中正在運行的進程

順便講一個Linux下的小技巧,比如我們在終端下,用鼠標選中一段文字,然后按一下鼠標中間的滾輪,就會在終端里黏貼選中的文字。
而在終端中拷貝和黏貼,需要用“Ctrl+Shift+C”和“Ctrl+Shift+V”來執行。

  • kill命令:結束一個進程
    Ctrl + C這個組合鍵只能作用于當前終端中正在運行的程序,而Linux中,很多進程是你看不到的,在后臺運行。

這時候就需要請出kill命令了。

kill命令后接需要結束的進程號,也就是之前我們看到過的PID。是一個數字,我們可以通過ps命令或top命令來獲知進程的PID。

kill 8461

我們也可以同時用kill來結束好幾個進程,只要用空格隔開它們的PID:

kill 8461 8561 1706

有時候,kill命令雖然作用于一個進程,但是它不終止,卡住了(因為kill命令會很友善地結束進程)。那怎么辦呢?有沒有比較簡單粗暴的方式呢?

是有的,我們可以用kill -9來立即強制結束進程。比如:

kill -9 7291

立即結束PID是7291的進程,非常“野蠻粗暴”。

killall:結束多個進程

記得我們之前提過,同一個程序運行時可能啟動多個進程。如果你想一下子結束所有這些進程,怎么做呢?

當然,你可以用kill + PID的方式一個個地結束這些進程,但是我們有一個更快捷的命令:killall。

all是英語《全部》的意思,所以killall命令就是用于結束全部要結束的進程。

不同于kill命令,killall命令后接程序名,而不是PID(進程號)。

假設現在我開了好幾個圖形終端,在每一個中我都運行find命令進行文件的查找。

這樣,我用ps -u oscar | grep find就可以搜索出好多個find的進程。

如果我要結束所有這些find進程,可以這么做:

killall find
halt命令和reboot命令:停止和重啟系統

既然我們剛學了如何用kill命令來結束進程,那么現在我們該來學習一下如何關閉和重啟整個Linux系統了吧。

halt:關閉系統

需要以root身份才能關閉系統,所以我們可以這么做:

sudo halt
reboot:重啟系統

同樣地,需要以root身份才能重啟系統。

實際上,halt和reboot這兩個命令都調用了Linux的另一個命令:shutdown

其實還有一個命令:poweroff也可以用于關機,而且非常有效率。

poweroff

后臺運行及合并多個終端

&符號和nohup命令:后臺運行進程

我們到目前為止用終端做的事情都是眼目所能及的,也就是說:我們運行的命令都是在前臺可見的。

這樣有一個好處是我們可以看到命令運行的過程,有什么問題可以及時發現。但是也有缺陷,例如有的命令運行耗時良久,我們又不想無所事事,怎么辦呢?難道我開一個終端專門執行一個耗時命令,然后為了能做其他事情,我再啟動一個終端,那也很不方便。而且,這樣的規避方法在非圖形界面的終端(還記得我們的tty1~tty6嗎?)中是難以實現的,因為只有一個終端窗口。

事實上,我們可以在同一個終端中同時運行好幾個命令。怎么做呢?就需要用到后臺進程的概念。

前臺進程和后臺進程

默認情況下,用戶創建的進程都是前臺進程。前臺進程從鍵盤讀取數據,并把處理結果輸出到顯示器。

我們可以看到前臺進程的運行過程。例如,使用 ls 命令來遍歷當前目錄下的文件。

這個程序就運行在前臺,它會直接把結果輸出到顯示器。如果 ls 命令需要數據(實際上不需要),那么它會等待用戶從鍵盤輸入。

當程序運行在前臺時,由于命令提示符($)還未出現,用戶不能輸入其他命令;即使程序需要運行很長時間,也必須等待程序運行結束才能輸入其他命令。

后臺進程與鍵盤沒有必然的關系。當然,后臺進程也可能會等待鍵盤輸入。

后臺進程的優點是不必等待程序運行結束就可以輸入其他命令。

那么怎么使一個進程(程序的實例)運行在后臺呢?

&符號:在后臺運行進程

前面說過,讓一個進程在后臺運行有幾種方法。

我們帶大家來學習第一種,很簡單:就是在你要運行的命令最后加上&這個符號。

我們可以用熟悉的cp命令做例子。例如,我運行cp命令來拷貝文件:emacs的軟件包。

cp emacs-24.4.tar.gz emacs-24.4-copy.tar.gz &

因為命令最后加了&符號,運行時此進程就成為了后臺進程。終端輸出了一些信息:

[1] 16525
  • [1]:這是此終端的后臺進程的標號。因為這是第一個后臺進程,所以標號為1。

  • 16525:這是進程號(PID),如果你想要結束這個后臺進程,你可以用我們上一課學習的kill命令:

kill 16525

我們雖然看不到這個拷貝進程的“所作所為”,但它確實在后臺默默進行著文件的拷貝。

如果我們用其他命令試一下,例如find命令,你會吃驚的。

例如我們運行:

find / -name "*log" &

但是你會發現,find命令雖然在后臺運行了,但是終端還是會不斷顯示所有找到的內容或錯誤信息。雖然我們還可以在終端中輸入其他命令,但是一直會跳出find搜索的結果還是很讓人感到厭煩的。最后小編不得不把它停止(用kill命令)。

幸好,我們之前學過重定向,我們可以把find的輸出結果重定向到文件里,就不會再來煩我們了。

find / -name "*log" > output_find &

這樣就不會一直有信息輸出了。

當然了,我們還可以更保險一些,將標準錯誤輸出也重定向到同一個文件,這樣就不會有任何輸出了。

find / -name "*log" > output_find 2>&1 &

但現在有一個問題:雖然我們的進程是被放到后臺了,在終端貌似看不到它的運行過程了。但是此進程還是與此終端相關聯的,假如我們把終端關閉,那么這個進程也就會結束。

nohup命令:使進程與終端分離

&符號雖然常用,但卻有一個不可忽視的缺點:后臺進程與終端相關聯,一旦終端關閉或者用戶登出,進程就自動結束。

如果我們想讓進程在以上情況下仍然繼續在后臺運行,那么我們須要用到nohup命令。

當用戶注銷(logout)或者網絡斷開時,終端會收到 HUP(是hangup的縮寫,英語《掛斷》的意思)信號從而關閉其所有子進程;終端被關閉時也會關閉其子進程。

我們可以用nohup命令使命令不受HUP信號影響。

我們用man來看一下nohup命令的解釋:

run a command immune to hangups, with output to a not-tty

翻譯出來大致就是:使得運行的命令不受hangup信號影響,而且輸出會存放到一個非tty中。

nohup命令的用法很簡單:在nohup命令之后接要運行的命令。

nohup ls

終端會輸出信息:ignoring input and appending output to nohup.out

大致意思是:忽略輸入,把輸出追加到nohup.out文件中。

使用nohup命令后,輸出會被默認地追加寫入到一個叫nohup.out的文件里。

現在,我們的進程已經不受終端關閉或者用戶斷開連接的影響了,會一直運行。當然了,用kill命令還是可以結束此進程的。

Ctrl + Z,jobs,bg和fg命令:控制進程的前后臺切換

我們來考慮一種情況:假如你要將進程轉到后臺運行,但是執行命令時忘記了在最后加上&符號。

如何再使此進程轉為后臺進程呢?有幾種方法。我們一一來學習。

Ctrl + Z:轉到后臺,并暫停運行

我們用top命令來演示。運行:

top

因為top命令的作用是實時地顯示各種系統信息和進程列表。這時,我們按下Ctrl + Z這個組合鍵:
可以看到終端顯示了

[1]+ Stopped top

這行信息。

bg命令:使進程轉到后臺

經過上面的Ctrl + Z操作,我們可憐的top進程轉入后臺,并且被暫停運行了。

輸入bg,然后回車。bg命令的作用是將命令轉入后臺運行。假如命令已經在后臺,并且暫停著,那么bg命令會將其狀態改為運行。

不加任何參數,bg命令會默認作用于最近的一個后臺進程,也就是剛才被Ctrl + Z暫停的top進程。如果后面加 %1,%2這樣的參數(不帶%,直接1,2這樣也可以),則是作用于指定標號的進程。因為進程轉入后臺之后,會顯示它在當前終端下的后臺進程編號。例如目前top進程轉入了后臺,它的進程編號是1(可以由[1]+推斷)。依次類推,bg %2就是作用于編號為2的后臺進程。

我們輸入bg,然后回車。看到如下輸出:

終端首先顯示了:

[1]+ top &

表示top命令被轉到了后臺,但是接著,它又顯示了這一條信息:

[1]+ Stopped top

咦,為什么top進程還是暫停著呢?anz理說bg命令會把在后臺暫停的進程重新喚醒,使之在后臺重新運行啊。

我們用ps命令來查看一下進程信息:

ps -aux

在上圖中可以看到,top這個進程的進程號是23051,狀態是T。

首先補充一些知識:

Linux中,進程有5種狀態:

  • 運行 (正在運行或在運行隊列中等待)
  • 中斷 (休眠中, 受阻, 在等待某個條件的形成或接受到信號)
  • 不可中斷 (收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生)
  • 僵死 (進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放)
  • 停止 (進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行運行)

ps命令標識進程的5種狀態碼:

  • D 不可中斷 uninterruptible sleep (usually IO)
  • R 運行 runnable (on run queue)
  • S 中斷 sleeping
  • T 停止 traced or stopped
  • Z 僵死 a defunct ("zombie") process

因此,我們的top進程的狀態還是T,也就是停止(stopped)的狀態。很奇怪是嗎?

我們用其他的命令來測試看看。我們測試find命令。首先運行:

find / -name "*log" > find_log 2>&1

上面這個命令的作用是:在根目錄 / 下查找以log結尾的文件,將標準輸出和標準錯誤輸出都重定向到find_log文件中。

因此,雖然上述命令在運行,但終端中看不到任何信息。

我們用Ctrl + Z來暫停此進程,并將其轉到后臺。然后再運行bg命令,使其重新在后臺運行。

但是并沒有顯示Stopped,奇怪了,為什么bg作用于暫停的find命令后,并沒有像剛才top命令一樣仍然顯示Stopped呢?

我們再用ps -aux 看一下:

可以看到,top命令的狀態是T,也就是停止(Stopped)。而find命令的狀態則是D,也即是不可中斷的睡眠(但其實是在運行,等會我們就會看到)。

疑問:所以小編也不清楚為什么對普通的命令(例如find),bg命令是起作用的,會將其轉成后臺運行。但是對于top命令,bg為什么不能將其轉成后臺運行,可能是因為top命令本身比較特殊吧。也許是因為top命令是前臺交互式命令,因此不能被置于后臺運行。

jobs命令:顯示后臺進程狀態

這個命令很強大。

jobs命令的作用是顯示當前終端里的后臺進程狀態。雖然我們可以用ps命令來查看進程狀態,但是ps命令輸出的進程列表太長了。

我們可以用jobs命令來顯示剛才那兩個進程的狀態:top進程和find進程。

jobs命令的輸出共分三列,我們逐列來說明:

  • 顯示后臺進程標號:比如上例中top進程的標號是1,find進程的標號是2,如果還有其他后臺進程,那么就會有[3],[4],等等。這個標號和PID(進程號)是不一樣的。這個標號只是顯示當前終端下的后臺進程的一個編號。

  • 顯示后臺進程狀態:比如Stopped是停止的意思,Running是運行的意思。還有其他狀態。

  • 命令本身。

可以看到,我們的top進程確實是在后臺暫停了,find進程在后臺運行,因為顯示Running。

fg命令:使進程轉到前臺

fg是英語foreground的意思,與bg命令相反,fg命令的作用是:使進程轉為前臺運行。

用法也很簡單,和bg一樣,如果不加參數,那么fg命令作用于最近的一個后臺進程。如果加參數,如%2,那么表示作用于本終端中第二個后臺進程。

我們用下面這個狀態圖來做個總結,應該就很清楚了:


解釋一下上圖:

  1. 如果我們運行一個程序,默認情況下,它會成為一個前臺運行的進程。我們可以按組合鍵Ctrl + C來銷毀此進程。

  2. 我們也可以使此進程在后臺運行。假如運行程序時就用&放在命令最后,那么進程就會在后臺運行。

  3. 假如在進程運行起來后,按Ctrl + Z,則進程會轉到后臺,并且停止。此時如果運行bg命令,則進程重新運行,并繼續在后臺。

  4. fg命令可以使進程轉到前臺,并且運行。

screen命令:合并多個終端

screen這個程序(所有命令其實都是程序)通常沒有在Linux發行版里預裝,如果你的Ubuntu系統里沒有screen這個程序,那么可以如此安裝:

sudo apt-get install screen

安裝完之后,你可以輸入screen命令。

screen命令用于在一個終端中打開多個終端,就好像在一個頁面中開多個標簽欄一樣
但是screen打開的多個終端是重疊在一起的,如果你不知道,還以為只是打開了一個終端,但是我們會學習如何在各個打開的終端間切換。

在我們運行了screen命令后,再用回車鍵跳過那頁介紹之后,我們看到終端里好像沒發生什么變化,就跟之前我們看到的終端一樣誒,那screen到底做了什么呢?

其實,screen為我們開了一個虛擬終端,就是在當前實際的終端里又開了一個終端。

如果你再運行screen,那么它又會新開一個虛擬終端。那么怎么退出每個新開的虛擬終端呢?可以按Ctrl + D或者用exit命令。

每次你按Ctrl + D或運行exit命令,都會關閉當前所在的虛擬終端,直到最后一個虛擬終端被關閉,screen程序退出,回到我們的實際終端里,如下圖:

上圖顯示了[screen is terminating],表示所有screen開的虛擬終端都已關閉,screen退出。

在screen程序中,幾乎所有的操作都是以Ctrl + a開始的。

以下所有的操作中,英文字母區分大小寫。也就是說:b和B是不同的,前者就是按下鍵盤上的b鍵,B則是需要用Shift + b。

如何操作呢?首先,按下Ctrl + a鍵,然后松開Ctrl鍵和a鍵,再按其他鍵來完成一定的操作。

  • Ctrl + a再加?號:顯示幫助頁面
    我們先用Ctrl + a鍵(也就是同時按下Ctrl鍵和a鍵),然后松開這兩個鍵,再按下?號
    可以看到,幫助頁面顯示了各種操作的實現方法。

比如說,你想要知道screen的版本號,那就是version,可以看到需要用到v鍵。但是光是按v鍵還不夠,因為我們看到第一頁第二行Command key: ^A ,就是說以下所有的操作,都需要先按下Ctrl + a鍵。^表示Ctrl鍵。

常用的組合按鍵

Ctrl + a,松開,再按c:創建一個新的虛擬終端。

Ctrl + a,松開,再按w:顯示當前虛擬終端的列表。會顯示在左下角。

Ctrl + a,松開,再按A:重命名當前虛擬終端。修改后的名字,你之后再用Ctrl + a,松開,再按w時就會看到。

Ctrl + a,松開,再按n:跳轉到下一個虛擬終端。

Ctrl + a,松開,再按p:跳轉到上一個虛擬終端。

Ctrl + a,松開,再按Ctrl + a:跳轉到最近剛使用的那個虛擬終端。

Ctrl + a,松開,再按09數字鍵:跳轉到第09號虛擬終端。

Ctrl + a,松開,再按 "(雙引號):會讓你選擇跳轉到哪個虛擬終端。

Ctrl + a,松開,再按k:關閉當前終端。

以上是一些常用的screen組合鍵,下面我們重點來看兩個很有用的組合鍵,分別用于分割虛擬終端和分離screen。

  • Ctrl + a,松開,再按S:分割虛擬終端為多個小虛擬終端
    注意是大寫的S,所以是Shif + s。如果這樣操作一次,則當前虛擬終端被分割為上下兩部分。如下圖所示:


如果再按這樣操作,就分割成3部分,4部分...

可以看到我在上面的半部分中運行了ls命令,下面的半部分暫時還沒跳轉過去操作,因此下半部分連命令行提示符也沒有,空空的。

那我們如何跳轉到下半部分去操作呢?

  • Ctrl + a,松開,再按Tab鍵。

光標就會跳轉到下半部分了,但是還是沒見有命令行提示符,那是因為還沒為下半部分創建虛擬終端呢。

所以我們可以新建一個:

  • Ctrl + a,松開,再按c。或者打開一個現有的虛擬終端。

可以看到,我們用Ctrl + a,松開,再按c之后,下半部分的左下角的--變成了3 bash,說明新建了一個虛擬終端,編號是3,也就是第4個(虛擬終端的編號從0開始)。

我們在這個3 bash的虛擬終端里運行top命令,如下:

那么我們如何關閉新分割出來的虛擬終端呢?

  • Ctrl + a,松開,再按X(是大寫的X,也就是Shift + x)。關閉新分割的虛擬終端。

  • Ctrl + a,松開,再按d:分離screen
    如果我們在screen程序中,就可以使screen程序與當前實際終端分離了,有點類似nohup命令的作用。這樣我們就可以重回我們自己的實際終端了,而screen并沒有退出,還在后臺運行。

如果你要重回screen中,可以輸入

screen -r

就又回到剛才的screen的虛擬終端里了。

我們可以使好幾個screen進入分離(detached)狀態。

之后再運行screen -r想要回去的時候,因為有兩個screen分離進程了,實際終端會詢問你要回到哪一個,如下圖:

你想要回到哪一個就用:

screen -r 編號

就可以了。例如我要回到6815那個screen,只要這樣:

screen -r 6815

如果你在實際終端下,輸入:

screen -ls

則會列出當前打開著的screen進程。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容