學(xué)習(xí)shell腳本前先對(duì)linux的基本常用知識(shí)點(diǎn)介紹一下。
- linux系統(tǒng)介紹
linux由四個(gè)部分組成,分別是linux內(nèi)核,GUN工具,圖形化桌面和應(yīng)用軟件,其中l(wèi)inux系統(tǒng)的核心就是內(nèi)核,負(fù)責(zé)計(jì)算機(jī)的硬件和軟件的管理。
1.1 linux內(nèi)核
linux內(nèi)核是系統(tǒng)的核心,控制著內(nèi)存,程序和硬件之間的交互。linux內(nèi)核主要負(fù)責(zé)四個(gè)功能,分別是內(nèi)存管理,軟件程序管理,硬件設(shè)備管理和文件系統(tǒng)管理。
1.1.1 內(nèi)存管理
內(nèi)核管理物理內(nèi)存和虛擬內(nèi)存,內(nèi)核通過(guò)交換空間實(shí)現(xiàn)虛擬內(nèi)存,交換空間實(shí)際上是硬盤(pán)上的一段區(qū)域,內(nèi)核會(huì)在交換空間和物理內(nèi)存之間交換虛擬內(nèi)存中的東西,從而會(huì)讓進(jìn)程以為他擁有比物理內(nèi)存更大的空間。內(nèi)存是由一個(gè)個(gè)頁(yè)面(page)組成的,內(nèi)核會(huì)把頁(yè)面放進(jìn)物理內(nèi)存或者交換空間,內(nèi)核會(huì)維護(hù)一個(gè)內(nèi)存頁(yè)面表,這個(gè)內(nèi)存頁(yè)面表會(huì)指明哪些頁(yè)面位于物理內(nèi)存,哪些頁(yè)面被換到了內(nèi)存上。
內(nèi)核會(huì)表明哪些頁(yè)面正在使用中,當(dāng)某個(gè)內(nèi)存頁(yè)面一段時(shí)間沒(méi)有被訪問(wèn)的時(shí)候,就會(huì)把該頁(yè)面換出到交換空間,換出操作與內(nèi)存是否還有可用的空間無(wú)關(guān),及時(shí)還有可用內(nèi)存,換出也可能會(huì)發(fā)生。當(dāng)進(jìn)程想要訪問(wèn)一段已經(jīng)被換出的內(nèi)存的頁(yè)面的時(shí)候,內(nèi)核會(huì)先在物理內(nèi)存中換出另外一個(gè)內(nèi)存頁(yè)面來(lái)騰出空間,然后從交換空間換入請(qǐng)求的內(nèi)存頁(yè)面。linux啟動(dòng)后,內(nèi)存頁(yè)面的換出操作就不會(huì)停止。
1.1.2 軟件程序管理
軟件程序就是進(jìn)程,內(nèi)核負(fù)責(zé)所有進(jìn)程的管理。內(nèi)核創(chuàng)建的第一個(gè)進(jìn)程為init進(jìn)程,這個(gè)進(jìn)程會(huì)啟動(dòng)系統(tǒng)上所有其他進(jìn)程。當(dāng)系統(tǒng)啟動(dòng)時(shí),它會(huì)把init進(jìn)程加載到虛擬內(nèi)存中,內(nèi)核在啟動(dòng)其他進(jìn)程的時(shí)候,也會(huì)在虛擬內(nèi)存中分配一塊區(qū)域來(lái)存儲(chǔ)該進(jìn)程的數(shù)據(jù)段和代碼段。
1.1.3 硬件設(shè)備管理
Linux把硬件設(shè)備當(dāng)做特殊的文件,稱(chēng)為設(shè)備文件。設(shè)備文件分為三類(lèi),分別是字符型設(shè)備文件,塊設(shè)備文件,網(wǎng)絡(luò)設(shè)備文件。
a) 字符設(shè)備文件指的是處理數(shù)據(jù)時(shí)每次只能處理一個(gè)字符的設(shè)備。比如終端就是個(gè)字符設(shè)備
b) 塊設(shè)備文件與字符設(shè)備文件類(lèi)似,不過(guò)塊設(shè)備文件每次能處理大塊數(shù)據(jù),比如硬盤(pán)
c) 網(wǎng)絡(luò)設(shè)備文件指的是用數(shù)據(jù)包發(fā)送和接收數(shù)據(jù)的設(shè)備,比如網(wǎng)卡和特殊回環(huán)設(shè)備,回環(huán)設(shè)備允許linux系統(tǒng)使用常用的網(wǎng)絡(luò)協(xié)議同自身通信,比如用tcp協(xié)議實(shí)現(xiàn)自己與自己通信(回環(huán)地址127.0.0.1)
linux系統(tǒng)為了方便管理硬件設(shè)備,為每個(gè)設(shè)備生成了一個(gè)稱(chēng)為節(jié)點(diǎn)的特殊文件,與設(shè)備的所有通信都通過(guò)設(shè)備節(jié)點(diǎn)完成,linux內(nèi)核為每個(gè)節(jié)點(diǎn)分配一個(gè)唯一的數(shù)值對(duì),這個(gè)數(shù)值對(duì)由主設(shè)備號(hào)和次設(shè)備號(hào),功能相近的設(shè)備被劃分到同樣的主設(shè)備號(hào)下,主設(shè)備號(hào)用于區(qū)分主設(shè)備組下某個(gè)特定設(shè)備。
1.1.4 文件系統(tǒng)管理
linux內(nèi)核支持通過(guò)不同類(lèi)型的文件系統(tǒng)從硬盤(pán)中讀寫(xiě)數(shù)據(jù),linux內(nèi)核采用VFS(虛擬文件系統(tǒng))作為和每個(gè)文件系統(tǒng)交互的接口。
1.2 GUN工具
GUN是GUN's Not Unix的縮寫(xiě),GUN是一套完整的Unix工具,這些工具開(kāi)源的,比如shell就是個(gè)GUN工具,注意,所有l(wèi)inux發(fā)行版默認(rèn)的shell都是bash shell。
1.3 圖形化桌面
有些linux發(fā)行版也是可以跟windows一樣通過(guò)圖標(biāo)操作的。我們把完成的linux系統(tǒng)包稱(chēng)作發(fā)行版,大多數(shù)發(fā)行版是為了某個(gè)特性用戶群定制的,比如軟件開(kāi)發(fā)人員,商業(yè)用戶等
1.4 應(yīng)用軟件
無(wú)
- shell命令
系統(tǒng)啟動(dòng)什么shell是根據(jù)用戶ID配置決定的,在文件/etc/passwd文件中,第7個(gè)字段就是該用戶對(duì)應(yīng)的默認(rèn)shell程序,只要用戶登錄到某個(gè)虛擬控制臺(tái)終端或在GUI中啟動(dòng)終端仿真器,默認(rèn)的shell程序就會(huì)運(yùn)行,比如下面root用戶對(duì)應(yīng)的默認(rèn)shell程序。
root:x:0:0:root:/root:/bin/bash
除此之外,/bin/sh是是另一個(gè)默認(rèn)的shell,這個(gè)shell是默認(rèn)的系統(tǒng)shell,用于那些需要在啟動(dòng)時(shí)使用的系統(tǒng)shell腳本,不過(guò)一般情況下會(huì)把默認(rèn)的系統(tǒng)shell軟連接到另一個(gè),比如我這個(gè)系統(tǒng)是ubuntu16.04
aitian@aitian-CW65S:~$ ll /bin/sh
lrwxrwxrwx 1 root root 4 1月 12 2019 /bin/sh -> dash*
2.1 shell基本操作
在linux早期,可以用來(lái)工作的只有shell,程序員都是通過(guò)終端輸入輸出,也就是通過(guò)文本命令行界面(Command line interface,CLI)。
2.1.1 啟動(dòng)shell
/etc/passwd文件包含了所有系統(tǒng)用戶賬號(hào)列表以及配置信息,取出這個(gè)文件中一行看看
root:x:0:0:root:/root:/bin/bash
這個(gè)條目用冒號(hào)分割,每個(gè)條目有七個(gè)字段,其中最后一個(gè)字段指定了用戶使用的shell程序,當(dāng)roo用戶用cli登錄系統(tǒng)linux系統(tǒng)的時(shí)候,bash shell會(huì)自動(dòng)啟動(dòng)。這個(gè)是cli默認(rèn)進(jìn)入的shell,如果用的話桌面版,可以指定其他的shell啟動(dòng)。
2.1.2 bash手冊(cè)
bash手冊(cè)可以查找一些shell命令,常用的命令是man。man + 想要查找的命令就可以找到相應(yīng)的手冊(cè)。比如輸入
man chmod
結(jié)果為:

輸入q之后就退出了。
如果不記得這個(gè)命令完整的名字的話,也可以使用關(guān)鍵字,比如輸入:
man -k chm
運(yùn)行后結(jié)果為
chmod (1) - change file mode bits
chmod (2) - change permissions of a file
fchmod (2) - change permissions of a file
fchmodat (2) - change permissions of a file
intel_upload_blit_large (1) - microbenchmark of Intel GPU performance
intel_upload_blit_large_gtt (1) - microbenchmark of Intel GPU performance
intel_upload_blit_large_map (1) - microbenchmark of Intel GPU performance
intel_upload_blit_small (1) - microbenchmark of Intel GPU performance
perf-bench (1) - General framework for benchmark suites
XF86VidModeSwitchMode (3) - Extension library for the XFree86-VidMode X extension
XkbLatchModifiers (3) - Latches and unlatches any of the eight real keyboard modifiers
還有一種查看手冊(cè)的方法是使用help指令,比如輸入
chmod --help
運(yùn)行后結(jié)果為:
用法:chmod [選項(xiàng)]... 模式[,模式]... 文件...
或:chmod [選項(xiàng)]... 八進(jìn)制模式 文件...
或:chmod [選項(xiàng)]... --reference=參考文件 文件...
Change the mode of each FILE to MODE.
With --reference, change the mode of each FILE to that of RFILE.
-c, --changes like verbose but report only when a change is made
-f, --silent, --quiet suppress most error messages
-v, --verbose output a diagnostic for every file processed
--no-preserve-root do not treat '/' specially (the default)
--preserve-root fail to operate recursively on '/'
--reference=RFILE use RFILE's mode instead of MODE values
-R, --recursive change files and directories recursively
--help 顯示此幫助信息并退出
--version 顯示版本信息并退出
Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+'.
2.1.3 cd命令
cd 命令用于切換到對(duì)應(yīng)目錄下,使用方法為cd + 相應(yīng)目錄。如果在cd命令后面沒(méi)有加目錄,就會(huì)自動(dòng)切換到用戶主目錄下。比如:
aitian@aitian-CW65S:~/at/shell/0$ pwd
/home/aitian/at/shell/0
aitian@aitian-CW65S:~/at/shell/0$ cd
aitian@aitian-CW65S:~$ pwd
/home/aitian
看上面的倒數(shù)第二行有一個(gè)波浪線(~),這個(gè)就表示用戶主目錄,比如輸入:
aitian@aitian-CW65S:~$ cd ~/protobuf352/
aitian@aitian-CW65S:~/protobuf352$ pwd
/home/aitian/protobuf352
aitian@aitian-CW65S:~/protobuf352$
單點(diǎn)符(.)表示當(dāng)前目錄;雙點(diǎn)符(..)表示上一級(jí)目錄。
2.1.4 ls命令
ls命令查看目錄下文件文件夾的名字,ls輸出的列表是按照字母排序的,不過(guò)要注意不是按照行排序,而是按照列排序。輸入:
aitian@aitian-CW65S:~$ ls
123 examples.desktop perf.data pycharm-community-2018.3.4 tags 公共的 視頻 文檔 音樂(lè)
at GoProject protobuf352 QtProject toLearn 模板 圖片 下載 桌面
ls命令本身額不能區(qū)分結(jié)果中哪個(gè)是文件哪個(gè)是文件夾,需要加上-F,比如:
aitian@aitian-CW65S:~$ ls -F
123* examples.desktop perf.data pycharm-community-2018.3.4/ tags 公共的/ 視頻/ 文檔/ 音樂(lè)/
at/ GoProject/ protobuf352/ QtProject/ toLearn 模板/ 圖片/ 下載/ 桌面/
文件夾名的最后后面有一個(gè)左斜杠(/),同時(shí)可以發(fā)現(xiàn)123作為一個(gè)可執(zhí)行文件,加上-F后會(huì)在他的后面加上一個(gè)星號(hào)(*),這些變區(qū)別不加-F都體現(xiàn)不出來(lái)。
如果想顯示隱藏文件,輸入:
ls -a
用-R參數(shù)可以遞歸地列出目錄的目錄一直到最底層的文件,比如:
aitian@aitian-CW65S:~/at$ ls -FR shell/
shell/:
0/ file tesfile test1.sh* test27.sh* test35.sh* test43.sh* test50.sh* testfile
17/ file1 test10.sh* test20.sh* test28.sh* test36.sh* test44.sh* test51.sh* test.txt
19/ file2 test11.sh* test21.sh* test29.sh* test37.sh* test45.sh* test52.sh* tmp.txt
1.txt file3 test12.sh* test22.sh* test2.sh* test38.sh* test46.sh* test53.sh* ttt.txt
20/ isPhone.sh* test13.sh* test23 test30.sh* test39.sh* test47.sh* test54.sh*
21/ main.c test14.sh* test23.sh* test31.sh* test3.sh* test48.sh* test5.sh*
bg.sh* mul@ test15.sh* test24.sh* test32.sh* test40.sh* test49.sh* test7.sh*
count_exe.sh* nohup.out test16.sh* test25.sh* test33.sh* test41.sh* test4.sh* test8.sh*
errfile normalfile test19.sh* test26.sh* test34.sh* test42.sh* test5 test9.sh*
shell/0:
shell/17:
1.sh* echo_function_value.sh* lib_call.sh* post_query_param_to_func.sh*
2.sh* global_variable.sh* local_variable.sh* return_array.sh*
3.sh* iter_function.sh* post_array_to_func_err_emample.sh*
4.sh* itertion.sh* post_array_to_func_ok_emample.sh*
shell/19:
aitian data destfile sedfile test test2 testfile value website
shell/20:
data data2 data3 data4 data5 data6 data7 data8 gawk_file gawk_file2 split.sh*
shell/21:
a.c a.out* data data2 data3 data4 data5 data6 data7 data8
ls命令中還可以使用正則表達(dá)式:
問(wèn)號(hào)?代表任何一個(gè)字符;
星號(hào)*代表0個(gè)或者多個(gè)任意字符
中括號(hào)列出所有范圍,比如[abc]或者[a-i]
還可以使用感嘆號(hào)將不需要的內(nèi)容排除在外,比如:
ls -l abc?def
ll abc*
ll ab[def]
ll a[!b]c
2.1.5 touch命令
touch可以創(chuàng)建文件,比如
touch a.txt
touch命令還可以改變文件的修改時(shí)間,注意這里并不會(huì)改變文件的內(nèi)容,比如:
aitian@aitian-CW65S:~/at$ ll vim.txt
-rw-rw-r-- 1 aitian aitian 11191 1月 5 00:26 vim.txt
aitian@aitian-CW65S:~/at$ touch vim.txt
aitian@aitian-CW65S:~/at$ ll vim.txt
-rw-rw-r-- 1 aitian aitian 11191 2月 9 21:25 vim.txt
2.1.6 cp命令
cp命令是復(fù)制作用,加上-i參數(shù)可以提示是否需要覆蓋同名文件,比如:
cp -i one two
復(fù)制文件夾的時(shí)候,在結(jié)尾加上-r,比如:
cp test . -r
cp命令也可以使用通配符。
2.1.7 鏈接文件
鏈接文件是linux的一大特色。在windows系統(tǒng)下,如果想維護(hù)同一個(gè)文件的兩份或者多份副本,那就把原來(lái)的文件拷貝招貼多份。而通過(guò)鏈接文件,可以保存一份物理文件副本和多個(gè)虛擬副本。
鏈接是目錄中,指向文件真實(shí)位置的占位符,linux中有兩種鏈接,一種是軟連接,又稱(chēng)為符號(hào)鏈接,另一種是硬鏈接。
2.1.7.1 軟鏈接
軟鏈接本身就是一個(gè)文件,這個(gè)文件指向另一個(gè)文件。軟鏈接文件和源文件完全是兩個(gè)文件,內(nèi)容也完全不同。要為一個(gè)文件創(chuàng)建軟鏈接,原文件必須預(yù)先存在。創(chuàng)建軟鏈接的格式為ln -s file soft_link_file,舉例如下:
aitian@aitian-CW65S:~/at/shell/0$ ln -s file file_soft
aitian@aitian-CW65S:~/at/shell/0$ ll
總用量 2008
drwxrwxr-x 2 aitian aitian 4096 2月 9 22:16 ./
drwxrwxr-x 8 aitian aitian 4096 2月 9 17:20 ../
-rw-rw-r-- 1 aitian aitian 2048000 2月 9 22:16 file
lrwxrwxrwx 1 aitian aitian 4 2月 9 22:13 file_soft -> file
后面的參數(shù)為軟鏈接文件名,它會(huì)指向前面的文件??梢钥闯鰞蓚€(gè)文件的大小也不一樣。通過(guò)inode數(shù)值也可以看出這兩個(gè)文件是完全不同的兩個(gè)文件,inode數(shù)值是linux內(nèi)核為文件分配的,是唯一的。輸入
aitian@aitian-CW65S:~/at/shell/0$ ls -i
539425 file 539423 file_soft
可以看出他們的inode不一樣。
2.1.7.2 硬鏈接
硬鏈接會(huì)創(chuàng)建一個(gè)虛擬文件,這個(gè)虛擬文件包含了原文件的信息以及位置。從根本上來(lái)說(shuō),這兩個(gè)文件是同一個(gè)文件。引用硬鏈接節(jié)是引用了原文件。
要?jiǎng)?chuàng)建硬鏈接,原文件也必須預(yù)先存在,舉例如下:
aitian@aitian-CW65S:~/at/shell/0$ ln file file_hard
aitian@aitian-CW65S:~/at/shell/0$ ll
總用量 4008
drwxrwxr-x 2 aitian aitian 4096 2月 9 22:22 ./
drwxrwxr-x 8 aitian aitian 4096 2月 9 17:20 ../
-rw-rw-r-- 2 aitian aitian 2048000 2月 9 22:16 file
-rw-rw-r-- 2 aitian aitian 2048000 2月 9 22:16 file_hard
lrwxrwxrwx 1 aitian aitian 4 2月 9 22:13 file_soft -> file
aitian@aitian-CW65S:~/at/shell/0$ ll -i file*
539425 -rw-rw-r-- 2 aitian aitian 2048000 2月 9 22:16 file
539425 -rw-rw-r-- 2 aitian aitian 2048000 2月 9 22:16 file_hard
539423 lrwxrwxrwx 1 aitian aitian 4 2月 9 22:13 file_soft -> file
從文件大小和inode數(shù)值可以看出,硬鏈接文件和原文件是同一個(gè)文件。所以說(shuō),你只要修改file文件或者file_hard中的任何一個(gè),另外一個(gè)會(huì)類(lèi)似量子糾纏一樣,產(chǎn)生完成相同的修改。
2.1.8 創(chuàng)建目錄
創(chuàng)建目錄使用mkdir+目錄名的格式,如果創(chuàng)建的目錄中還有別的目錄,那么就加上-p命令:
aitian@aitian-CW65S:~/at/shell/0$ mkdir -p a/b/c
aitian@aitian-CW65S:~/at/shell/0$ ls -R a/
a/:
b
a/b:
c
a/b/c:
2.1.9 file命令
file命令能夠確定文件的類(lèi)型以及文件的字符編碼,比如下面的test.sh是文本內(nèi)容,輸入:
aitian@aitian-CW65S:~/at/shell/0$ file test.sh
test.sh: ASCII text
假如是一個(gè)目錄呢?
aitian@aitian-CW65S:~/at/shell/0$ file abc
abc: directory
假如是一個(gè)軟鏈接文件的話,還是指出鏈接到哪個(gè)文件:
aitian@aitian-CW65S:~/at/shell/0$ file file_soft
file_soft: symbolic link to file
如果是一個(gè)二進(jìn)制文件,還能看出來(lái)這個(gè)二進(jìn)制文件可以在什么平臺(tái)運(yùn)行
aitian@aitian-CW65S:~/at/shell/0$ file main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 2.6.32, BuildID[sha1]=f0b96f8607c66ae35df14c6381c5af7e2dc8a174, not stripped
2.1.10 cat命令
cat命令可以在終端打印出文本內(nèi)容,比如:
aitian@aitian-CW65S:~/at/shell/0$ cat main.c
#include<stdio.h>
int main()
{
return 0;
}
加上-n參數(shù)可以顯示行號(hào),比如:
1 #include<stdio.h>
2 int main()
3 {
4
5
6 return 0;
7 }
如果只想給有文本的行加上行號(hào)的話,加上-b參數(shù):
1 #include<stdio.h>
2 int main()
3 {
4
5 return 0;
6 }
注意這里的第四行也被顯示出來(lái)了,因?yàn)檫@一行有很多空格,而不是一個(gè)空行。
2.1.11 more命令
cat命令一般用來(lái)查看小文本文件比較好用,遇到大文件的時(shí)候可以用more。比如輸入:
more test.c

可以發(fā)現(xiàn),左下角顯示了當(dāng)前瀏覽的位置,按q可以退出,按空格鍵或者回車(chē)鍵向前運(yùn)行。
2.1.12 less命令
跟more命令用法差不多
less test.c
2.1.13 head命令
head命令可以用來(lái)顯示文件開(kāi)頭一些行的內(nèi)容,如果沒(méi)有加任何參數(shù)的話就是顯示前10行。比如文本log.txt的內(nèi)容為:
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20
輸入:
head log.txt
結(jié)果為:
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
也可以用-n參數(shù)顯示打印最前面的n行,輸入:
head -5 log.txt
結(jié)果為:
line 1
line 2
line 3
line 4
line 5
2.1.14 tail命令
tail命令打印文件末尾的內(nèi)容,如果不加任何參數(shù),就默認(rèn)打印末尾10行內(nèi)容,比如文本log.txt的內(nèi)容為:
line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20
輸入:
tail log.txt
結(jié)果為:
line 11
line 12
line 13
line 14
line 15
line 16
line 17
line 18
line 19
line 20
也可以通過(guò)-n參數(shù)指定打印默認(rèn)的多行內(nèi)容,輸入:
tail -5 log.txt
tail命令中還有一個(gè)常用并且非常好用的參數(shù)就是-f,比如在終端使用tail -f log.txt后,當(dāng)另一個(gè)進(jìn)程向log.txt寫(xiě)入內(nèi)容的時(shí)候,在終端可以實(shí)時(shí)顯示新寫(xiě)入的內(nèi)容。比如

可以看出,在下面的終端中寫(xiě)入line 21的時(shí)候,上面的終端實(shí)時(shí)地顯示了這一行新增的內(nèi)容。
2.1.15 ps命令
ps命令能查看系統(tǒng)中進(jìn)程相關(guān)的信息,對(duì)于ps命令而言,可以帶的參數(shù)實(shí)在太多了,其實(shí)不需要記住所有的參數(shù),只要記住自己常用的就行了。比如ps -ef可以顯示系統(tǒng)上運(yùn)行的所有進(jìn)程,輸入:
ps -ef|more
結(jié)果為:

ps -ef可以顯示出系統(tǒng)上運(yùn)行的所有進(jìn)程,其中-e表示顯示所有運(yùn)行在系統(tǒng)上的進(jìn)程,-f表示則擴(kuò)展打印出一些列,這些列包含很多重要信息,比如上圖所示,其中:
UID表示啟動(dòng)進(jìn)程的用戶;
PID和PPID表示進(jìn)程和該進(jìn)程父進(jìn)程的ID;
C表示進(jìn)程周期中的CPU利用率;
STIME表示進(jìn)程啟動(dòng)的系統(tǒng)時(shí)間;
TTY表示進(jìn)程啟動(dòng)的終端設(shè)備;
TIME表示進(jìn)程占用的CPU時(shí)間,注意這不是運(yùn)行時(shí)間;
CMD表示啟動(dòng)的程序名稱(chēng);
上面的參數(shù)應(yīng)該非常多了,如果想要更多的參數(shù)的話加上-l(小寫(xiě)的L),比如輸入:
ps -l
結(jié)果為:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 3676 3665 0 80 0 - 6339 wait pts/3 00:00:00 bash
4 R 1000 5547 3676 0 80 0 - 7664 - pts/3 00:00:00 ps
可以發(fā)現(xiàn)只用一個(gè)-l參數(shù)的話只會(huì)顯示當(dāng)前控制臺(tái)下屬于當(dāng)前用戶的進(jìn)程,新增的列有:
F表示內(nèi)核分配給進(jìn)程的系統(tǒng)標(biāo)記;
S表示狀態(tài),狀態(tài)有以下幾種:
D 不可中斷 Uninterruptible sleep (usually IO)
R 正在運(yùn)行,或在隊(duì)列中的進(jìn)程
S 處于休眠狀態(tài)
T 停止或被追蹤
Z 僵尸進(jìn)程
W 進(jìn)入內(nèi)存交換(從內(nèi)核2.6開(kāi)始無(wú)效)
X 死掉的進(jìn)程
PRI表示進(jìn)程的優(yōu)先級(jí),數(shù)字越大表示優(yōu)先級(jí)越低
NI謙讓度值用來(lái)參與決定優(yōu)先級(jí)
ADDR石金成的內(nèi)存地址
SZ表示進(jìn)程被換出,所需交換空間的大致大小
WACHAN表示進(jìn)程休眠的內(nèi)核函數(shù)的地址
如果輸入ps l的話與ps -l的結(jié)果基本相同,前者是BSD風(fēng)格,后者是unix風(fēng)格,比如輸入:
ps l
結(jié)果為:
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
0 1000 3676 3665 20 0 25356 6248 wait Ss pts/3 0:00 /bin/bash
4 1000 12893 3676 20 0 30656 1500 - R+ pts/3 0:00 ps l
其中
VSZ表示進(jìn)程在內(nèi)存中的大小,以KB為單位
RSS進(jìn)程在未換出來(lái)時(shí)的占用的物理內(nèi)存
STAT代表進(jìn)程轉(zhuǎn)臺(tái)的雙字符狀態(tài)碼,這個(gè)雙字符狀態(tài)碼的第一個(gè)字符和unix風(fēng)格的含義相同,第二個(gè)字符為:
< 高優(yōu)先級(jí)
N 低優(yōu)先級(jí)
L 有些頁(yè)被鎖進(jìn)內(nèi)存
s 包含子進(jìn)程
+ 位于后臺(tái)的進(jìn)程組;
l 多線程,克隆線程 multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
還有一個(gè)用法我個(gè)人非常喜歡,輸入ps axuf,這個(gè)指令可以顯示父子進(jìn)程的關(guān)系:
ps axuf
結(jié)果為:

2.1.16 top命令
ps命令有一個(gè)缺點(diǎn),就是只能在某個(gè)特定時(shí)間點(diǎn)顯示進(jìn)程信息,如果想動(dòng)態(tài)顯示內(nèi)存變化等,可以使用top信息。
輸入:
top
結(jié)果為:

該結(jié)果中:
第一行有4個(gè)參數(shù),分別是當(dāng)前系統(tǒng)時(shí)間(時(shí):分:秒),系統(tǒng)運(yùn)行時(shí)間(時(shí):分),登陸的用戶個(gè)數(shù),系統(tǒng)的平均負(fù)載。其中平均負(fù)載有3個(gè)值,分別是最近1分鐘,最近5分鐘和最近15分鐘的平均負(fù)載,值越大說(shuō)明負(fù)載越高。一般情況下,最近一分鐘如果有高負(fù)載不足為奇,但如果最近15分鐘的負(fù)載都非常高,那就有問(wèn)題了。一般情況下,如果系統(tǒng)負(fù)載超過(guò)2,就說(shuō)明系統(tǒng)比較繁忙。
第二行顯示了進(jìn)程的個(gè)數(shù)信息,有5個(gè)參數(shù),分別是進(jìn)程總個(gè)數(shù),當(dāng)前運(yùn)行進(jìn)程個(gè)數(shù),睡眠的今晨個(gè)數(shù),停止的今晨個(gè)數(shù),僵尸進(jìn)程個(gè)數(shù)。
第三行顯示了CPU相關(guān)信息,分別是us:用戶態(tài)使用的cpu時(shí)間比
sy:系統(tǒng)態(tài)使用的cpu時(shí)間比
ni:用做nice加權(quán)的進(jìn)程分配的用戶態(tài)cpu時(shí)間比
id:空閑的cpu時(shí)間比
wa:cpu等待磁盤(pán)寫(xiě)入完成時(shí)間
hi:硬中斷消耗時(shí)間
si:軟中斷消耗時(shí)間
st:虛擬機(jī)偷取時(shí)間
第四行是物理內(nèi)存相關(guān)信息,分別是總共的物理內(nèi)存,空閑的物理內(nèi)存,當(dāng)前使用了多少物理內(nèi)存,緩存區(qū)占用的內(nèi)存,其中
cache是高速緩存,用于CPU和內(nèi)存之間的緩沖
buffer是I/O緩存,用于內(nèi)存和硬盤(pán)的緩沖
第五行是交換空的內(nèi)存。
剩下的都是對(duì)一個(gè)個(gè)進(jìn)程的描述了,其中
PID是進(jìn)程的ID
USER是進(jìn)程所屬用戶的名字
PR表示進(jìn)程的優(yōu)先級(jí)
NI表示進(jìn)程的謙讓度值
VIRT表示虛擬內(nèi)存大小
RES表示物理內(nèi)存大小
SHR表示進(jìn)程或其他進(jìn)程共享的內(nèi)存總量
S是進(jìn)程的狀態(tài)
CPU是進(jìn)程使用的cpu比例
MEM是進(jìn)程使用的內(nèi)存占可用內(nèi)存的比例
TIME是從進(jìn)程啟動(dòng)后到當(dāng)前占用的cpu時(shí)間,而不是運(yùn)行的總時(shí)間
COMMAND是進(jìn)程對(duì)應(yīng)的程序名
默認(rèn)情況下,是按照cpu使用率排序的,如果想要修改排序標(biāo)準(zhǔn),按f后移動(dòng)上下方向鍵到新的字段上,然后輸入s,然后按q退出就行了。
2.1.17 kill命令和killall命令
kill命令使用方法是kill -n pid,表示將n號(hào)信號(hào)發(fā)給pid對(duì)應(yīng)的進(jìn)程,還有一個(gè)命令是killall 進(jìn)程名。比如輸入:
kill -9 2786
killall tcp*
第一條命令是把KILL信號(hào)(9號(hào)信號(hào))發(fā)給2786對(duì)應(yīng)的進(jìn)程
第二條命令是把所有tcp開(kāi)頭的進(jìn)程都結(jié)束掉。
2.1.18 df命令和du命令
df命令可以查看所有已掛載磁盤(pán)的使用情況,比如輸入:
aitian@aitian-CW65S:~$ df
文件系統(tǒng) 1K-塊 已用 可用 已用% 掛載點(diǎn)
udev 4006220 0 4006220 0% /dev
tmpfs 805608 9576 796032 2% /run
/dev/sdb5 122669092 24513164 91901644 22% /
tmpfs 4028032 7640 4020392 1% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 4028032 0 4028032 0% /sys/fs/cgroup
tmpfs 805608 52 805556 1% /run/user/1000
每一列的解釋如下:
第一列為設(shè)備的設(shè)備位置;
第二列表示能容納多少個(gè)1024字節(jié)大小的塊;
第三列表示已使用多少個(gè)1024字節(jié)大小的塊;
第四列表示當(dāng)前還可用多少個(gè)1024大小字節(jié)的塊;
第五列表示以已經(jīng)使用的比例;
第六列表示設(shè)備掛載到了那個(gè)掛載點(diǎn)。
df命令可以加-h參數(shù),這個(gè)參數(shù)能夠靈活地調(diào)整大小單位,輸入:
aitian@aitian-CW65S:~$ df -h
文件系統(tǒng) 容量 已用 可用 已用% 掛載點(diǎn)
udev 3.9G 0 3.9G 0% /dev
tmpfs 787M 9.4M 778M 2% /run
/dev/sdb5 117G 24G 88G 22% /
tmpfs 3.9G 7.5M 3.9G 1% /dev/shm
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs 787M 52K 787M 1% /run/user/1000
df命令能夠查看某個(gè)磁盤(pán)空間使用情況,如果發(fā)現(xiàn)某個(gè)磁盤(pán)空間使用占用很大的時(shí)候,可以繼續(xù)使用du命令看看具體什么目錄下有大文件,默認(rèn)情況下du命令是查看當(dāng)前目錄下所有文件,所有目錄,所有子目錄的磁盤(pán)使用情況,當(dāng)前也可以指定你想看哪個(gè)目錄,比如:
aitian@aitian-CW65S:~/at$ du -ch googletest/
1.2M googletest/googletest/test
8.0K googletest/googletest/scripts/test
136K googletest/googletest/scripts
448K googletest/googletest/src
20K googletest/googletest/include/gtest/internal/custom
244K googletest/googletest/include/gtest/internal
508K googletest/googletest/include/gtest
512K googletest/googletest/include
120K googletest/googletest/samples
168K googletest/googletest/docs
36K googletest/googletest/cmake
6.6M googletest/googletest
704K googletest/googlemock/test
116K googletest/googlemock/scripts/generator/cpp
148K googletest/googlemock/scripts/generator
192K googletest/googlemock/scripts
92K googletest/googlemock/src
24K googletest/googlemock/include/gmock/internal/custom
68K googletest/googlemock/include/gmock/internal
620K googletest/googlemock/include/gmock
624K googletest/googlemock/include
240K googletest/googlemock/docs
12K googletest/googlemock/cmake
1.9M googletest/googlemock
44K googletest/ci
8.6M googletest/
8.6M 總用量
其中c表示顯示已列出文件的總大小,h參數(shù)表示靈活使用單位。發(fā)現(xiàn)df和du命令使用-h參數(shù)非常方便,其實(shí)ls命令也可以使用-h參數(shù)的。
2.1.19 sort命令
sort命令對(duì)文本按照字典順序排序,數(shù)字在字母前面,大小字母在小寫(xiě)字母前面,比如a.txt內(nèi)容為:
wu lin wai zhuan
Wu lin feng
zhao ben shan
Zeng zeng zeng
liu lao gen
ye shen ren bu jing
123
78
5
輸入:
sort a.txt
結(jié)果為:
123
5
78
liu lao gen
Wu lin feng
wu lin wai zhuan
ye shen ren bu jing
Zeng zeng zeng
zhao ben shan
可以發(fā)現(xiàn),雖然字符串正常的排序了,但是數(shù)字并沒(méi)有按照先小后大的順序排序,這是因?yàn)槟J(rèn)情況下,數(shù)字是被當(dāng)作字符串處理的,如果想數(shù)字按照大小排序的話,加上-n參數(shù)。
aitian@aitian-CW65S:~/at/shell/0$ sort -n a.txt
liu lao gen
Wu lin feng
wu lin wai zhuan
ye shen ren bu jing
Zeng zeng zeng
zhao ben shan
5
78
123
還有一種用法,非常常用。sort剛才sort排序的時(shí)候默認(rèn)用的是第一列,比如
aitian@aitian-CW65S:~/at/shell/0$ du -cs *|sort -n
0 0
0 file_soft
4 abc
4 a.txt
4 log.txt
4 test.c
4 test.sh
4 testshell.sh
12 a.out
12 main
2004 file
2052 總用量
如果不想用第一列,而是想要其他列的數(shù)據(jù)怎么辦呢?可以使用-k參數(shù),-k參數(shù)就是告訴sort命令使用第幾列的數(shù)據(jù)進(jìn)行排序,比如有一個(gè)文件b.txt的內(nèi)容為:
aitian@aitian-CW65S:~/at/shell/0$ sort -k 2 -n b.txt
liuliuliu -7 90
hululu 0 89
wulinwaizhuan 34 567
chenchenchen 79 1089
aitian@aitian-CW65S:~/at/shell/0$ sort -k 3 -n b.txt
hululu 0 89
liuliuliu -7 90
wulinwaizhuan 34 567
chenchenchen 79 1089
可以發(fā)現(xiàn)上面有一個(gè)負(fù)數(shù)-7也能被正確排序,其實(shí)不僅僅符號(hào),浮點(diǎn)數(shù)也可以的。那這里有一個(gè)問(wèn)題,sort是怎么知道第一列第二列的呢?實(shí)際上默認(rèn)情況下,sort根據(jù)空格制表符,也就是空白區(qū)域來(lái)分割以列數(shù)據(jù)。有時(shí)候需要用特定的分割符號(hào)來(lái)進(jìn)行分割,這個(gè)時(shí)候使用-t參數(shù),比如喲一個(gè)文件c.txt,內(nèi)容為:
wulinwaizhuan-0.34-567
hululu-0.01-89
chenchenchen-0.79-1089
liuliuliu-0.7-90
輸入:
aitian@aitian-CW65S:~/at/shell/0$ sort -t '-' -k 2 -n c.txt
hululu-0.01-89
wulinwaizhuan-0.34-567
liuliuliu-0.7-90
chenchenchen-0.79-1089
之前所有的命令都是牲畜輸出,可以加上-r參數(shù)改成降序輸出
aitian@aitian-CW65S:~/at/shell/0$ du -c *|sort -nr
2060 總用量
2004 file
12 main
12 a.out
4 testshell.sh
4 test.sh
4 test.c
4 log.txt
4 c.txt
4 b.txt
4 a.txt
4 abc
0 file_soft
0 0
2.1.20 tar命令
tar命令可以歸檔文件,對(duì)文件進(jìn)行壓縮或者解壓,比如
aitian@aitian-CW65S:~/at/shell/0$ tar -cvf target.tar abc/ a.txt
abc/
abc/aaa
a.txt
aitian@aitian-CW65S:~/at/shell/0$ tar -tf target.tar
abc/
abc/aaa
a.txt
aitian@aitian-CW65S:~/at/shell/0$ tar -xvf target.tar
abc/
abc/aaa
a.txt
其中tar -cvf 對(duì)后面的所有目錄和文件壓縮到target.tar文件,tar -tf列出target.tar文件中的內(nèi)容,tar -xvf對(duì)target.tar文件進(jìn)行解壓。
2.2 shell父子進(jìn)程
2.2.1 shell父子進(jìn)程關(guān)系
當(dāng)在shell的cli輸入bash之后,會(huì)開(kāi)啟一個(gè)新的shell進(jìn)程,并且是第一個(gè)shell的子進(jìn)程,比如:
aitian@aitian-CW65S:~$ ps -f
UID PID PPID C STIME TTY TIME CMD
aitian 5307 5296 0 10:59 pts/2 00:00:00 /bin/bash
aitian 6115 5307 0 11:07 pts/2 00:00:00 ps -f
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ ps -f
UID PID PPID C STIME TTY TIME CMD
aitian 5307 5296 0 10:59 pts/2 00:00:00 /bin/bash
aitian 6116 5307 0 11:07 pts/2 00:00:00 bash
aitian 6149 6116 0 11:08 pts/2 00:00:00 ps -f
aitian@aitian-CW65S:~$ echo $$
6116
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $$
5307
通過(guò)pid和ppid可以看出父子進(jìn)程關(guān)系,通過(guò)exit退出的是子進(jìn)程的shell,通過(guò)$$打印當(dāng)前shell的進(jìn)程pid。
當(dāng)前通過(guò)輸入ps -uf可以看出父子進(jìn)程的關(guān)系:
aitian@aitian-CW65S:~$ ps -uf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
aitian 5307 0.0 0.0 25304 6012 pts/2 Ss 10:59 0:00 /bin/bash
aitian 7187 0.0 0.0 25316 6088 pts/2 S 11:12 0:00 \_ bash
aitian 7471 0.0 0.0 39104 3300 pts/2 R+ 11:14 0:00 \_ ps -uf
通過(guò)上面可以看出,ps命令實(shí)際上是bash拉起的一個(gè)新的進(jìn)程。
2.2.2 進(jìn)程列表
如果有多個(gè)命令想要執(zhí)行,可以通過(guò)分號(hào)(;)隔開(kāi),這樣所有的命令都會(huì)依次執(zhí)行,例如
aitian@aitian-CW65S:~/at$ pwd;cd shell/;pwd
/home/aitian/at
/home/aitian/at/shell
aitian@aitian-CW65S:~/at/shell$ pwd
/home/aitian/at/shell
不過(guò)這所有的命令都是父進(jìn)程執(zhí)行的命令,如果想構(gòu)造成進(jìn)程列表,必須加上小括號(hào)。
aitian@aitian-CW65S:~/at$ (pwd;cd shell/;pwd)
/home/aitian/at
/home/aitian/at/shell
aitian@aitian-CW65S:~/at$ pwd
/home/aitian/at
從上面的結(jié)果可以看出兩個(gè)pwd打印出來(lái)的內(nèi)容是完全相同的。但是,加上括號(hào)之后是新開(kāi)了一個(gè)子進(jìn)程來(lái)執(zhí)行括號(hào)中的命令,但是不加括號(hào)是父進(jìn)程直接執(zhí)行的。不過(guò)看第四行可以看出差別。不加括號(hào)的時(shí)候,執(zhí)行是父進(jìn)程執(zhí)行命令,所有命令執(zhí)行之后,當(dāng)前路徑為/home/aitian/at/shell??梢允褂眠M(jìn)程列表之后,當(dāng)前的路徑是/home/aitian/at,這是因?yàn)樗械拿疃际亲舆M(jìn)程在運(yùn)行,運(yùn)行后退回主進(jìn)程。
還有一個(gè)方法可以判斷是否生成了子shell,那就是通過(guò)打印BASH_SUBSHELL的值,比如輸入:
aitian@aitian-CW65S:~/at$ pwd;echo $BASH_SUBSHELL
/home/aitian/at
0
aitian@aitian-CW65S:~/at$ (pwd;echo $BASH_SUBSHELL)
/home/aitian/at
1
注意括號(hào)里面可以再加括號(hào),比如輸入:
aitian@aitian-CW65S:~/at$ (pwd;(pwd;echo $BASH_SUBSHELL))
/home/aitian/at
/home/aitian/at
2
這說(shuō)明子shell會(huì)再生成新的shell去執(zhí)行命令。
2.2.3 后臺(tái)模式運(yùn)行進(jìn)程
通過(guò)在命令的結(jié)尾加上&符號(hào)可以讓命令在后臺(tái)運(yùn)行,同時(shí)讓出CLI,比如:
aitian@aitian-CW65S:~/at$ sleep 100&
[1] 14305
aitian@aitian-CW65S:~/at$ ps -f
UID PID PPID C STIME TTY TIME CMD
aitian 5307 5296 0 10:59 pts/2 00:00:00 /bin/bash
aitian 7187 5307 0 11:12 pts/2 00:00:00 bash
aitian 14305 7187 0 11:55 pts/2 00:00:00 sleep 100
aitian 14306 7187 0 11:55 pts/2 00:00:00 ps -f
aitian@aitian-CW65S:~/at$ jobs
[1]+ 運(yùn)行中 sleep 100 &
aitian@aitian-CW65S:~/at$ jobs -l
[1]+ 14305 運(yùn)行中 sleep 100 &
上面的結(jié)果中,先以后臺(tái)模式運(yùn)行sleep命令,會(huì)自動(dòng)打印出一個(gè)后臺(tái)信息,其中方括號(hào)中的1表示后臺(tái)作業(yè)號(hào),后面是pid。通過(guò)ps -f可看到sleep進(jìn)程。通過(guò)jobs命令可以看到當(dāng)前在后臺(tái)模式的所有用戶的作業(yè),jobs -l可以看出作業(yè)對(duì)應(yīng)的pid。
不僅僅命令后面加&符號(hào)可以讓其在后臺(tái)運(yùn)行,運(yùn)行bash命令的后面加上&也可以使其后臺(tái)運(yùn)行。
2.3 外部命令和內(nèi)建命令
2.3.1 外部命令
外部命令是文件系統(tǒng)命令,不是shell程序的一部分,通常位于/bin,/usr/bin,/sbin或/usr/sbin中,比如ps命令就是一個(gè)外部命令。比如:
aitian@aitian-CW65S:~/at/shell$ which ps
/bin/ps
aitian@aitian-CW65S:~/at/shell$ type -a ps
ps 是 /bin/ps
當(dāng)外部命令執(zhí)行時(shí),會(huì)創(chuàng)建出一個(gè)子進(jìn)程。
2.3.2 內(nèi)建命令
內(nèi)建命令是屬于shell的一部分,內(nèi)建命令在shell中被執(zhí)行的時(shí)候是不會(huì)創(chuàng)建子進(jìn)程的。比如cd命令
aitian@aitian-CW65S:~/at/shell$ type -a cd
cd 是 shell 內(nèi)建
2.3.2.1 history內(nèi)建命令
history命令打印出用過(guò)的命令,比如
2048 which ps
2049 type -a ps
2050 type -a cd
2051 history
2052 history|more
2053 history|less
2054 history -n 10
2055 clear
2056 history -a
2057 history
2058 pwd
2059 history
越往后是最新的。
2.3.2.2 alias命令
alias命令也是內(nèi)建命令,可以給命令指定一個(gè)別名,輸入:
aitian@aitian-CW65S:~/at/shell$ alias pbc='pwd'
aitian@aitian-CW65S:~/at/shell$ pbc
/home/aitian/at/shell
- 環(huán)境變量
環(huán)境變量是存儲(chǔ)有關(guān)shell會(huì)話和工作環(huán)境的信息,環(huán)境變量允許腳本輕松訪問(wèn)他們,環(huán)境變量分為全局變量和局部變量。
3.1 全局環(huán)境變量
全局環(huán)境變量對(duì)于shell會(huì)話和所有生成的子shell都是有效的,局部變量則只對(duì)變量創(chuàng)建的shell有效。要查看全局變量可以使用env或者printenv命令。
aitian@aitian-CW65S:~/at/shell$ printenv
LC_PAPER=zh_CN.UTF-8
XDG_VTNR=7
ORBIT_SOCKETDIR=/tmp/orbit-aitian
XDG_SESSION_ID=c2
LC_ADDRESS=zh_CN.UTF-8
CLUTTER_IM_MODULE=xim
IBUS_DISABLE_SNOOPER=1
TERMINATOR_UUID=urn:uuid:08541795-c8ff-4ab7-8692-dcb8925f822f
LC_MONETARY=zh_CN.UTF-8
如果想要查看指定的變量:
aitian@aitian-CW65S:~/at/shell$ printenv HOME
/home/aitian
aitian@aitian-CW65S:~/at/shell$ echo $HOME
/home/aitian
3.2 局部環(huán)境變量
局部環(huán)境變量只能在定義它們的進(jìn)程中可見(jiàn),set命令會(huì)顯示進(jìn)程設(shè)置的所有環(huán)境變量,包括全局環(huán)境變量,局部環(huán)境變量和用戶自定義變量。比如輸入:
aitian@aitian-CW65S:~/at/shell$ a=xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$ set|grep xiangcunaiqing
a=xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$ env|grep xiangcunaiqing
aitian@aitian-CW65S:~/at/shell$
set命令會(huì)顯示出全局變量,局部變量和用戶自定義變量,同時(shí)set命令會(huì)對(duì)結(jié)果進(jìn)行排序,不過(guò)env和printenv不會(huì)對(duì)結(jié)果進(jìn)行排序,也不會(huì)輸出局部變量和用戶自定義變量。
3.3 設(shè)置變量
可以在shell中設(shè)置變量,比如創(chuàng)建當(dāng)前shell進(jìn)程內(nèi)有效的局部變量,比如:
aitian@aitian-CW65S:~$ echo $variable
aitian@aitian-CW65S:~$ variable=str_test
aitian@aitian-CW65S:~$ echo $variable
str_test
這個(gè)局部變量只能在當(dāng)前的shell中有效,在其他的shell中無(wú)法訪問(wèn)。比如:
aitian@aitian-CW65S:~$ var=xiangcun
aitian@aitian-CW65S:~$ echo $var
xiangcun
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $var
父進(jìn)程設(shè)置的局部變量在子進(jìn)程中是無(wú)法訪問(wèn)的,同時(shí)子進(jìn)程設(shè)置的局部變量在父進(jìn)程也是無(wú)法訪問(wèn)的。如果想要父進(jìn)程的變量在子進(jìn)程也可以訪問(wèn),那么必須使用全局變量,使用export導(dǎo)出全局變量。
aitian@aitian-CW65S:~$ variable1="xiang cun ai qing"
aitian@aitian-CW65S:~$ echo $variable
str_test
aitian@aitian-CW65S:~$ export variable
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $variable
str_test
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $variable
str_test
要注意,在父進(jìn)程導(dǎo)出的全局變量,子進(jìn)程可以訪問(wèn),但是如果在子進(jìn)程修改這個(gè)全局變量的值,不會(huì)影響父進(jìn)程該全局變量的值。比如:
aitian@aitian-CW65S:~$ var2="liu lao gen"
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
aitian@aitian-CW65S:~$ export var2
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
aitian@aitian-CW65S:~$ var2="gen lao liu"
aitian@aitian-CW65S:~$ echo $var2
gen lao liu
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $var2
liu lao gen
可以看出子進(jìn)程修改了全局環(huán)境變量的值,但是父進(jìn)程該全局變量的值并沒(méi)有改變。這是因?yàn)閷?shí)際上,全局變量是父進(jìn)程繼承給子進(jìn)程的,可以理解子進(jìn)程的內(nèi)存空間里面也有這個(gè)值,并且其初始值就是父進(jìn)程中設(shè)置的值。所以說(shuō),這個(gè)全局變量是繼承的。如果我們重新打開(kāi)一個(gè)新的shell,是無(wú)法訪問(wèn)其他shell export出來(lái)的變量的,因?yàn)檫@之間沒(méi)有繼承關(guān)系。
如果在子進(jìn)程中export一個(gè)全局變量,在父進(jìn)程中無(wú)法訪問(wèn)這個(gè)全局變量,因?yàn)楦高M(jìn)程無(wú)法繼承子進(jìn)程中的變量。
aitian@aitian-CW65S:~$ echo $var
aitian@aitian-CW65S:~$ bash
aitian@aitian-CW65S:~$ var=123
aitian@aitian-CW65S:~$ export var
aitian@aitian-CW65S:~$ echo $var
123
aitian@aitian-CW65S:~$ exit
exit
aitian@aitian-CW65S:~$ echo $var
全局變量也可以刪除,使用unset命令,比如:
aitian@aitian-CW65S:~$ var=123
aitian@aitian-CW65S:~$ export var
aitian@aitian-CW65S:~$ printenv var
123
aitian@aitian-CW65S:~$ unset var
aitian@aitian-CW65S:~$ printenv var
aitian@aitian-CW65S:~$
3.4 設(shè)置PATH環(huán)境變量
當(dāng)在shell中輸入一個(gè)外部命令的時(shí)候,shell怎么去找這個(gè)程序在哪里呢?PATH環(huán)境變量定義了用于進(jìn)行程序查找的目錄,比如:
aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin
這里面的路徑用冒號(hào)分隔開(kāi),這里使用了sed命令換行顯示??梢园涯硞€(gè)目錄加到PATH環(huán)境變量中,比如:
aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin
aitian@aitian-CW65S:~$ PATH=$PATH:/home/root
aitian@aitian-CW65S:~$ printenv PATH|sed -n 's/:/\n/g p'
/opt/ros/kinetic/bin
/usr/lib/jvm/java-8-openjdk-amd64/bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
/home/aitian/GoProject
/usr/local/go/bin
/home/root
3.5 系統(tǒng)環(huán)境變量
如果在PATH里面添加一個(gè)路徑,當(dāng)重啟系統(tǒng)或者退出這個(gè)shell之后,新增的路徑就沒(méi)有了。所以需要設(shè)置系統(tǒng)環(huán)境變量,也就是任何用戶在重啟系統(tǒng)之后都可以繼續(xù)訪問(wèn)最新的變量。
3.5.1 /etc/profile文件
/etc/profile文件是bash shell默認(rèn)的主啟動(dòng)文件, 只要一登錄linux系統(tǒng),bash就會(huì)執(zhí)行/etc/profile啟動(dòng)文件中的命令,這個(gè)文件或?qū)С鲆恍┫到y(tǒng)環(huán)境變量。
3.5.2 用戶專(zhuān)屬啟動(dòng)文件
除了/etc/profile文件外,還有4個(gè)啟動(dòng)文件,這4個(gè)啟動(dòng)文件都起著相同的作用,都是用來(lái)提供用戶專(zhuān)屬的環(huán)境變量。這四個(gè)文件都位于用戶的HOME目錄下,分別是:
$HOME/.bash_profile
$HOME/.bashrc
$HOME/.bash_login
$HOME/.profile
當(dāng)然,大多數(shù)linux發(fā)行版只用這4個(gè)啟動(dòng)文件中的一個(gè)或者兩個(gè)。用戶可以編輯這些文件為自己添加自己專(zhuān)屬的環(huán)境變量,這些環(huán)境變量會(huì)在每次啟動(dòng)bash shell的時(shí)候生效。
注意一般情況下,都把變量放進(jìn).bashrc文件或者放進(jìn)/etc/profile文件中。
3.6 數(shù)組變量
數(shù)組變量可以存儲(chǔ)多個(gè)值,比如
aitian@aitian-CW65S:~$ array=(apple banana cindy dog egg)
aitian@aitian-CW65S:~$ echo $array
apple
aitian@aitian-CW65S:~$ echo ${array[2]}
cindy
aitian@aitian-CW65S:~$ echo ${array[*]}
apple banana cindy dog egg
aitian@aitian-CW65S:~$ array[2]=fruit
aitian@aitian-CW65S:~$ echo ${array[*]}
apple banana fruit dog egg
- linux安全
linux安全是通過(guò)用戶和組根據(jù)每個(gè)文件和目錄的安全性設(shè)置來(lái)訪問(wèn)文件,linux安全的核心是用戶賬戶,每個(gè)能進(jìn)入linux系統(tǒng)的用戶都會(huì)被分配唯一的用戶賬戶,用戶對(duì)系統(tǒng)中各種對(duì)象的訪問(wèn)權(quán)限取決于用戶。用戶權(quán)限是通過(guò)創(chuàng)建用戶時(shí)分配的用戶ID(UID)來(lái)跟蹤的,UID是一個(gè)數(shù)字。
4.1 /etc/passwd文件
linux系統(tǒng)用/etc/passwd文件將用戶的登錄名匹配到對(duì)應(yīng)的UID,比如:
aitian@aitian-CW65S:~$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
root用戶賬戶是linux系統(tǒng)的管理員,對(duì)應(yīng)的UID永遠(yuǎn)為0.其余還有一些UID是1或者2或者3這樣的,那是針對(duì)特殊服務(wù)設(shè)定的UID。LINUX為系統(tǒng)賬戶預(yù)留了500已下的UID。上面一行數(shù)據(jù)通過(guò)冒號(hào)分隔開(kāi),一共有7個(gè)字段,分別是:
用戶名,用戶密碼,UID,組ID(GID),用戶賬戶的文本描述,用戶HOME目錄的位置,用戶默認(rèn)的shell。
4.2 /etc/shadow文件
上面的密碼段被寫(xiě)成了x,真正的密碼存儲(chǔ)在/etc/shadow中,只有特定的程序比如登錄程序才能訪問(wèn)這個(gè)文件。比如:
aitian@aitian-CW65S:~$ sudo cat /etc/shadow
[sudo] aitian 的密碼:
root:!:17908:0:99999:7:::
daemon:*:16911:0:99999:7:::
bin:*:16911:0:99999:7:::
sys:*:16911:0:99999:7:::
4.3 用戶設(shè)置
用戶設(shè)置包括添加新用戶,刪除用戶,修改用戶。
4.3.1 添加新用戶
添加新用戶的時(shí)候有一些缺省值,如下:
aitian@aitian-CW65S:~$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no
上面的默認(rèn)值的含義是:
新用戶被添加到GID為100的公共組
新用戶的HOME目錄為/home/登錄名
新用戶賬戶密碼過(guò)期后不會(huì)被禁用
新用戶賬戶未被設(shè)置過(guò)期日期
默認(rèn)的shell是bash shell
系統(tǒng)會(huì)把/etc/skel目錄下的內(nèi)容復(fù)制到用戶的HOME目錄下
系統(tǒng)為該用戶賬戶在mail目錄下創(chuàng)一個(gè)用于接收郵件的文件
其中/etc/skel中的內(nèi)容為:
aitian@aitian-CW65S:~$ ls -al /etc/skel/
總用量 44
drwxr-xr-x 2 root root 4096 7月 28 2019 .
drwxr-xr-x 152 root root 12288 2月 14 21:21 ..
-rw-r--r-- 1 root root 220 9月 1 2015 .bash_logout
-rw-r--r-- 1 root root 3771 9月 1 2015 .bashrc
-rw-r--r-- 1 root root 8980 4月 20 2016 examples.desktop
-rw-r--r-- 1 root root 2181 11月 2 2015 .kshrc
-rw-r--r-- 1 root root 655 5月 16 2017 .profile
這些都是標(biāo)準(zhǔn)啟動(dòng)文件。
現(xiàn)在來(lái)新增一個(gè)用戶并查看:
aitian@aitian-CW65S:~$ sudo useradd -m new_user
[sudo] aitian 的密碼:
aitian@aitian-CW65S:~$ ls -al /home/new_user/
總用量 36
drwxr-xr-x 2 new_user new_user 4096 2月 23 18:04 .
drwxr-xr-x 6 root root 4096 2月 23 18:04 ..
-rw-r--r-- 1 new_user new_user 220 9月 1 2015 .bash_logout
-rw-r--r-- 1 new_user new_user 3771 9月 1 2015 .bashrc
-rw-r--r-- 1 new_user new_user 8980 4月 20 2016 examples.desktop
-rw-r--r-- 1 new_user new_user 2181 11月 2 2015 .kshrc
-rw-r--r-- 1 new_user new_user 655 5月 16 2017 .profile
這里的-m參數(shù)是讓他創(chuàng)建HOME目錄,如果不加-m參數(shù),對(duì)應(yīng)的牡蠣將不會(huì)被創(chuàng)建。這里的創(chuàng)建用的都是默認(rèn)值。除了-m之外,還有一些其他的參數(shù)可以指定別的參數(shù)而不使用默認(rèn)值。
4.3.2 刪除用戶
userdel命令可以刪除用戶,默認(rèn)情況下,如果不加任何參數(shù),只會(huì)刪除/etc/passwd文件中的用戶信息,而不會(huì)刪除系統(tǒng)中屬于該賬戶的任何文件。如果-r參數(shù),會(huì)刪除用戶的HOME目錄以及郵件目錄,但是系統(tǒng)上仍可能存在用戶的其他文件。
aitian@aitian-CW65S:/home$ sudo userdel -r new_user
[sudo] aitian 的密碼:
userdel: new_user 郵件池 (/var/mail/new_user) 未找到
4.3.4 修改用戶
修改用戶要用特定命令。
4.3.4.1 usermod 根據(jù)指定的參數(shù)修改對(duì)應(yīng)的值
4.3.4.2 passwd和chpasswd修改用戶密碼
aitian@aitian-CW65S:/home$ sudo passwd new_user
輸入新的 UNIX 密碼:
重新輸入新的 UNIX 密碼:
passwd:已成功更新密碼
aitian@aitian-CW65S:/home$ su new_user
密碼:
new_user@aitian-CW65S:/home$ id
uid=1001(new_user) gid=1002(new_user) 組=1002(new_user)
4.4 用戶組
/etc/group文件包含系統(tǒng)上用到的組的信息,比如:
aitian@aitian-CW65S:/home$ cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
.
.
.
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
這里的四個(gè)字段分別是:組名,組密碼,GID,屬于該組的用戶列表
4.4.1 創(chuàng)建新組
groupadd命令用于新增一個(gè)group,比如
aitian@aitian-CW65S:/home$ sudo groupadd new_group
[sudo] aitian 的密碼:
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
new_group:x:1003:
從最后兩行可以發(fā)現(xiàn),new_user用戶對(duì)應(yīng)的GID是1002.對(duì)應(yīng)的組名也叫new_user,new_group對(duì)應(yīng)的UID為1003.
通過(guò)usermod修改一個(gè)用戶對(duì)應(yīng)的group,比如:
aitian@aitian-CW65S:/home$ sudo usermod -G new_group new_user
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
new_group:x:1003:new_user
4.4.2 修改組
groupmod命令用于修改已有組的信息,通過(guò)-g修改GID,通過(guò)-n修改組名。所有的權(quán)限都是基于GID的,所以可以隨意改變組名不會(huì)影響安全性。比如
aitian@aitian-CW65S:/home$ sudo groupmod -n rename_group new_group
[sudo] aitian 的密碼:
aitian@aitian-CW65S:/home$ tail /etc/group
pulse:x:124:
pulse-access:x:125:
rtkit:x:126:
saned:x:127:
aitian:x:1000:
sambashare:x:128:aitian
docker:x:999:aitian
snn:x:1001:aitian
new_user:x:1002:
rename_group:x:1003:new_use
- 文件權(quán)限
首先看下面的結(jié)果:
aitian@aitian-CW65S:~/at/shell$ ll test9.sh
-rwxrwxrwx 1 aitian aitian 54 12月 7 23:00 test9.sh*
這里的3組rwx分別是,文件的屬主s,文件的屬組,系統(tǒng)其他用戶的權(quán)限。