基本概念及操作
常用快捷鍵
常用通配符
man
man 1 ls
所有的手冊(cè)頁(yè)遵循一個(gè)常見的布局掂僵,為了通過(guò)簡(jiǎn)單的 ASCII 文本展示而被優(yōu)化,而這種情況下可能沒有任何形式的高亮或字體控制怨喘。一般包括以下部分內(nèi)容:
NAME(名稱) 該命令或函數(shù)的名稱音诈,接著是一行簡(jiǎn)介逞敷。
SYNOPSIS(概要) 對(duì)于命令,正式的描述它如何運(yùn)行蚯涮,以及需要什么樣的命令行參數(shù)治专。對(duì)于函數(shù),介紹函數(shù)所需的參數(shù)遭顶,以及哪個(gè)頭文件包含該函數(shù)的定義张峰。
DESCRIPTION(說(shuō)明) 命令或函數(shù)功能的文本描述。
EXAMPLES(示例) 常用的一些示例液肌。
SEE ALSO(參見) 相關(guān)命令或函數(shù)的列表挟炬。
也可能存在其它部分內(nèi)容,但這些部分沒有得到跨手冊(cè)頁(yè)的標(biāo)準(zhǔn)化嗦哆。常見的例子包括:OPTIONS(選項(xiàng))谤祖,EXIT STATUS(退出狀態(tài)),ENVIRONMENT(環(huán)境)老速,BUGS(程序漏洞)粥喜,F(xiàn)ILES(文件),AUTHOR(作者)橘券,REPORTING BUGS(已知漏洞)额湘,HISTORY(歷史)和 COPYRIGHT(版權(quán))。
軟件安裝
sudo apt-get update
sudo apt-get install sysvbanner
用戶及文件權(quán)限管理
查看用戶
who am i
who mom likes
who -m
who 命令其它常用參數(shù)
創(chuàng)建用戶
一般我們登錄系統(tǒng)時(shí)都是以普通賬戶的身份登錄的旁舰,要?jiǎng)?chuàng)建用戶需要 root 權(quán)限锋华,這里就要用到 sudo 這個(gè)命令了。不過(guò)使用這個(gè)命令有兩個(gè)大前提箭窜,一是你要知道當(dāng)前登錄用戶的密碼毯焕,二是當(dāng)前用戶必須在 sudo 用戶組。
su <user> 可以切換到用戶 user磺樱,執(zhí)行時(shí)需要輸入目標(biāo)用戶的密碼纳猫,sudo <cmd> 可以以特權(quán)級(jí)別運(yùn)行 cmd 命令,需要當(dāng)前用戶屬于 sudo 組竹捉,且需要輸入當(dāng)前用戶的密碼芜辕。su - <user> 命令也是切換用戶,但是同時(shí)用戶的環(huán)境變量和工作目錄也會(huì)跟著改變成目標(biāo)用戶所對(duì)應(yīng)的块差。
sudo adduser lilei
ls /home
su -l lileiwho am i
whoami
pwd
退出當(dāng)前用戶跟退出終端一樣侵续,可以使用 exit 命令或者使用快捷鍵 Ctrl+D倔丈。
用戶組
在 Linux 里面每個(gè)用戶都有一個(gè)歸屬(用戶組),用戶組簡(jiǎn)單地理解就是一組用戶的集合状蜗,它們共享一些資源和權(quán)限乃沙,同時(shí)擁有私有資源,就跟家的形式差不多诗舰,你的兄弟姐妹(不同的用戶)屬于同一個(gè)家(用戶組)警儒,你們可以共同擁有這個(gè)家(共享資源),爸媽對(duì)待你們都一樣(共享權(quán)限)眶根,你偶爾寫寫日記蜀铲,其他人未經(jīng)允許不能查看(私有資源和權(quán)限)。當(dāng)然一個(gè)用戶是可以屬于多個(gè)用戶組的属百,正如你既屬于家庭记劝,又屬于學(xué)校或公司族扰。
groups lilei
其中冒號(hào)之前表示用戶厌丑,后面表示該用戶所屬的用戶組。這里可以看到 lilei用戶屬于 lilei用戶組渔呵,每次新建用戶如果不指定用戶組的話怒竿,默認(rèn)會(huì)自動(dòng)創(chuàng)建一個(gè)與用戶名相同的用戶組(差不多就相當(dāng)于家長(zhǎng)的意思)。
默認(rèn)情況下在 sudo 用戶組里的可以使用 sudo 命令獲得 root 權(quán)限扩氢。
cat /etc/group | sort
cat /etc/group | grep -E "lilei"
/etc/group 的內(nèi)容包括用戶組(Group)、用戶組口令录豺、GID(組 ID) 及該用戶組所包含的用戶(User)朦肘,每個(gè)用戶組一條記錄。
如果用戶的 GID 等于用戶組的 GID双饥,那么最后一個(gè)字段 user_list 就是空的媒抠,這里的 GID 是指用戶默認(rèn)所在組的 GID,可以使用 id 命令查看咏花。
默認(rèn)情況下新創(chuàng)建的用戶是不具有 root 權(quán)限的趴生,也不在 sudo 用戶組,可以讓其加入 sudo 用戶組從而獲取 root 權(quán)限:
su -l lilei
sudo ls
使用 usermod 命令可以為用戶添加用戶組迟螺,同樣使用該命令你必需有 root 權(quán)限冲秽,你可以直接使用 root 用戶為其它用戶添加用戶組舍咖,或者用其它已經(jīng)在 sudo 用戶組的用戶使用 sudo 命令獲取權(quán)限來(lái)執(zhí)行該命令矩父。
su - jachin
當(dāng)然也可以通過(guò) sudo passwd shiyanlou 進(jìn)行設(shè)置,或者你直接關(guān)閉當(dāng)前終端打開一個(gè)新的終端排霉。
groups lilei
sudo usermod -G sudo lilei
groups lilei
然后再切換回 lilei 用戶窍株,現(xiàn)在就可以使用 sudo 獲取 root 權(quán)限了。
sudo ls /
刪除用戶和用戶組
sudo deluser lilei --remove-home
使用 --remove-home 參數(shù)在刪除用戶時(shí)候會(huì)一并將該用戶的工作目錄一并刪除。如果不使用那么系統(tǒng)會(huì)自動(dòng)在 /home 目錄為該用戶保留工作目錄球订。
刪除用戶組可以使用 groupdel 命令后裸,倘若該群組中仍包括某些用戶,則必須先刪除這些用戶后冒滩,才能刪除群組微驶。
ls -l
關(guān)于文件類型,這里有一點(diǎn)你必需時(shí)刻牢記 Linux 里面一切皆文件开睡,正因?yàn)檫@一點(diǎn)才有了設(shè)備文件( /dev 目錄下有各種設(shè)備文件因苹,大都跟具體的硬件設(shè)備相關(guān))這一說(shuō)。 socket:網(wǎng)絡(luò)套接字篇恒。pipe 管道扶檐。軟鏈接文件:鏈接文件是分為兩種的,另一種當(dāng)然是“硬鏈接”(硬鏈接不常用胁艰,而軟鏈接等同于 Windows 上的快捷方式)
讀權(quán)限款筑,表示你可以使用 cat <file name> 之類的命令來(lái)讀取某個(gè)文件的內(nèi)容;寫權(quán)限腾么,表示你可以編輯和修改某個(gè)文件的內(nèi)容奈梳;
執(zhí)行權(quán)限,通常指可以運(yùn)行的二進(jìn)制程序文件或者腳本文件解虱,如同 Windows 上的 exe 后綴的文件颈嚼,不過(guò) Linux 上不是通過(guò)文件后綴名來(lái)區(qū)分文件的類型。你需要注意的一點(diǎn)是饭寺,一個(gè)目錄同時(shí)具有讀權(quán)限和執(zhí)行權(quán)限才可以打開并查看內(nèi)部文件阻课,而一個(gè)目錄要有寫權(quán)限才允許在其中創(chuàng)建其它文件,這是因?yàn)槟夸浳募?shí)際保存著該目錄里面的文件的列表等信息艰匙。
所屬用戶組權(quán)限限煞,是指你所在的用戶組中的所有其它用戶對(duì)于該文件的權(quán)限,比如员凝,你有一個(gè) iPad署驻,那么這個(gè)用戶組權(quán)限就決定了你的兄弟姐妹有沒有權(quán)限使用它破壞它和占有它。
鏈接到該文件所在的 inode 結(jié)點(diǎn)的文件名數(shù)目健霹,以 inode 結(jié)點(diǎn)大小為單位來(lái)表示的文件大小旺上,你可以給 ls 加上 -lh 參數(shù)來(lái)更直觀的查看文件的大小。
ls -a
顯示除了 .(當(dāng)前目錄)和 ..(上一級(jí)目錄)之外的所有文件糖埋,包括隱藏文件(Linux 下以 . 開頭的文件為隱藏文件)宣吱。
ls -al
查看某一個(gè)目錄的完整屬性,而不是顯示目錄里面的文件屬性
ls -dl
顯示所有文件大小瞳别,并以普通人類能看懂的方式呈現(xiàn)
ls -asSh
變更文件所有者
su -l lilei
pwd
touch iphone11
ls -alh iphone11
cd /home/lilei
ls iphone11
sudo chown jachin iphone11
ls -alh iphone11
修改文件權(quán)限
如果你有一個(gè)自己的文件不想被其他用戶讀征候、寫杭攻、執(zhí)行,那么就需要對(duì)文件的權(quán)限做修改疤坝。
二進(jìn)制數(shù)字表示
每個(gè)文件有三組固定的權(quán)限兆解,分別對(duì)應(yīng)擁有者,所屬用戶組跑揉,其他用戶锅睛,記住這個(gè)順序是固定的。文件的讀寫執(zhí)行對(duì)應(yīng)字母 rwx历谍,以二進(jìn)制表示就是 111衣撬,用十進(jìn)制表示就是 7。
echo "echo \"hello shiyanlou\"" > iphone11
chmod 600 iphone11
ls -alh iphone11
su -l lilei
echo "hello" >iphone11
cat iphone11
加減賦值操作
chmod go-rw iphone11
ls -alh
g扮饶、o 還有 u 分別表示 group(用戶組)具练、others(其他用戶) 和 user(用戶),+ 和 - 分別表示增加和去掉相應(yīng)的權(quán)限甜无。
Linux 目錄結(jié)構(gòu)及文件基本操作
Linux 目錄結(jié)構(gòu)
Linux 的目錄與 Windows 的目錄的區(qū)別扛点,一種不同是體現(xiàn)在目錄與存儲(chǔ)介質(zhì)(磁盤,內(nèi)存岂丘,DVD 等)的關(guān)系上陵究,以往的 Windows 一直是以存儲(chǔ)介質(zhì)為主的,主要以盤符(C 盤奥帘,D 盤...)及分區(qū)來(lái)實(shí)現(xiàn)文件管理铜邮,然后之下才是目錄,目錄就顯得不是那么重要寨蹋,除系統(tǒng)文件之外的用戶文件放在任何地方任何目錄也是沒有多大關(guān)系松蒜。所以通常 Windows 在使用一段時(shí)間后,磁盤上面的文件目錄會(huì)顯得雜亂無(wú)章(少數(shù)善于整理的用戶除外吧)已旧。然而 UNIX/Linux 恰好相反秸苗,UNIX 是以目錄為主的,Linux 也繼承了這一優(yōu)良特性运褪。 Linux 是以樹形目錄結(jié)構(gòu)的形式來(lái)構(gòu)建整個(gè)系統(tǒng)的惊楼,可以理解為樹形目錄是一個(gè)用戶可操作系統(tǒng)的骨架。雖然本質(zhì)上無(wú)論是目錄結(jié)構(gòu)還是操作系統(tǒng)內(nèi)核都是存儲(chǔ)在磁盤上的秸讹,但從邏輯上來(lái)說(shuō) Linux 的磁盤是“掛在”(掛載在)目錄上的檀咙,每一個(gè)目錄不僅能使用本地磁盤分區(qū)的文件系統(tǒng),也可以使用網(wǎng)絡(luò)上的文件系統(tǒng)璃诀。舉例來(lái)說(shuō)愉阎,可以利用網(wǎng)絡(luò)文件系統(tǒng)(Network File System悼嫉,NFS)服務(wù)器載入某特定目錄等步咪。
FHS 標(biāo)準(zhǔn)
FHS 定義了兩層規(guī)范,第一層是, / 下面的各個(gè)目錄應(yīng)該要放什么文件數(shù)據(jù)氧秘,例如 /etc 應(yīng)該放置設(shè)置文件年鸳,/bin 與 /sbin 則應(yīng)該放置可執(zhí)行文件等等。第二層則是針對(duì) /usr 及 /var 這兩個(gè)目錄的子目錄來(lái)定義丸相。例如 /var/log 放置系統(tǒng)日志文件搔确,/usr/share 放置共享數(shù)據(jù)等等。
tree /
目錄路徑
使用 cd 命令可以切換目錄灭忠,在 Linux 里面使用 . 表示當(dāng)前目錄膳算,.. 表示上一級(jí)目錄(注意,以 . 開頭的文件都是隱藏文件弛作,所以這兩個(gè)目錄必然也是隱藏的涕蜂,可以使用 ls -a 命令查看隱藏文件),- 表示上一次所在目錄映琳,~ 通常表示當(dāng)前用戶的 home 目錄机隙。使用 pwd 命令可以獲取當(dāng)前所在路徑(絕對(duì)路徑)。
關(guān)于絕對(duì)路徑萨西,簡(jiǎn)單地說(shuō)就是以根" / "目錄為起點(diǎn)的完整路徑有鹿,以你所要到的目錄為終點(diǎn),表現(xiàn)形式如: /usr/local/bin谎脯,表示根目錄下的 usr 目錄中的 local 目錄中的 bin 目錄葱跋。
相對(duì)路徑,也就是相對(duì)于你當(dāng)前的目錄的路徑源梭,相對(duì)路徑是以當(dāng)前目錄 . 為起點(diǎn)娱俺,以你所要到的目錄為終點(diǎn),表現(xiàn)形式如: usr/local/bin (這里假設(shè)你當(dāng)前目錄為根目錄)废麻。你可能注意到矢否,我們表示相對(duì)路徑實(shí)際并沒有加上表示當(dāng)前目錄的那個(gè) . ,而是直接以目錄名開頭脑溢,因?yàn)檫@個(gè) usr 目錄為 / 目錄下的子目錄僵朗,是可以省略這個(gè) . 的。如果是當(dāng)前目錄的上一級(jí)目錄屑彻,則需要使用 .. 验庙,比如你當(dāng)前目錄為 /home/shiyanlou 目錄下,根目錄就應(yīng)該表示為 ../../ 社牲,表示上一級(jí)目錄( home 目錄)的上一級(jí)目錄( / 目錄)粪薛。
cd /usr/local/bin/
cd ../../../usr/local/bin/
新建文件
使用 touch 命令創(chuàng)建空白文件,關(guān)于 touch 命令搏恤,其主要作用是來(lái)更改已有文件的時(shí)間戳的(比如违寿,最近訪問(wèn)時(shí)間湃交,最近修改時(shí)間),但其在不加任何參數(shù)的情況下藤巢,只指定一個(gè)文件名搞莺,則可以創(chuàng)建一個(gè)指定文件名的空白文件(不會(huì)覆蓋已有同名文件)。
touch test
使用 mkdir(make directories)命令可以創(chuàng)建一個(gè)空目錄掂咒,也可同時(shí)指定創(chuàng)建目錄的權(quán)限屬性才沧。
mkdir mydir
使用 -p 參數(shù),同時(shí)創(chuàng)建父目錄(如果不存在該父目錄)绍刮,如下我們同時(shí)創(chuàng)建一個(gè)多級(jí)目錄(這在安裝軟件温圆、配置安裝路徑時(shí)非常有用):
mkdir -p father/son/grandson
若當(dāng)前目錄已經(jīng)創(chuàng)建了一個(gè) test 文件,再使用 mkdir test 新建同名的文件夾孩革,系統(tǒng)會(huì)報(bào)錯(cuò)文件已存在岁歉。若當(dāng)前目錄存在一個(gè) test 文件夾,則 touch 命令膝蜈,則會(huì)更改該文件夾的時(shí)間戳而不是新建文件刨裆。
復(fù)制
使用 cp 命令(copy)復(fù)制一個(gè)文件到指定目錄。
cp test father/son/grandson/
要成功復(fù)制目錄需要加上 -r 或者 -R 參數(shù)彬檀,表示遞歸復(fù)制帆啃。
cd /home/shiyanlou
mkdir family
cp -r father family
** 刪除**
使用 rm(remove files or directories)命令刪除一個(gè)文件:
rm test
有時(shí)候你會(huì)遇到想要?jiǎng)h除一些為只讀權(quán)限的文件,直接使用 rm 刪除會(huì)顯示一個(gè)提示窍帝,忽略這提示努潘,直接刪除文件,可以使用 -f 參數(shù)強(qiáng)制刪除:
rm -f test
跟復(fù)制目錄一樣坤学,要?jiǎng)h除一個(gè)目錄疯坤,也需要加上 -r 或 -R 參數(shù):
rm -r family
遇到權(quán)限不足刪除不了的目錄也可以和刪除文件一樣加上 -f 參數(shù):
rm -rf family
移動(dòng)文件與文件重命名
使用 mv(move or rename files)命令移動(dòng)文件(剪切)。
mkdir Documents
touch file1
mv file1 Documents
mv 命令除了能移動(dòng)文件外深浮,還能給文件重命名压怠。
mv file1 myfile
要實(shí)現(xiàn)批量重命名,mv 命令就有點(diǎn)力不從心了飞苇,我們可以使用一個(gè)看起來(lái)更專業(yè)的命令 rename 來(lái)實(shí)現(xiàn)菌瘫。不過(guò)它要用 perl 正則表達(dá)式來(lái)作為參數(shù)。
touch file{1..5}.txt
rename 's/\.txt/\.c/' *.txt
rename 'y/a-z/A-Z/' *.c
rename 是先使用第二個(gè)參數(shù)的通配符匹配所有后綴為 .txt 的文件布卡,然后使用第一個(gè)參數(shù)提供的正則表達(dá)式將匹配的這些文件的 .txt 后綴替換為 .c雨让。
查看文件
使用 cat,tac 和 nl 命令查看文件
前兩個(gè)命令都是用來(lái)打印文件內(nèi)容到標(biāo)準(zhǔn)輸出(終端)忿等,其中 cat 為正序顯示栖忠,tac 為倒序顯示。
標(biāo)準(zhǔn)輸入輸出:當(dāng)我們執(zhí)行一個(gè) shell 命令行時(shí)通常會(huì)自動(dòng)打開三個(gè)標(biāo)準(zhǔn)文件,即標(biāo)準(zhǔn)輸入文件(stdin)庵寞,默認(rèn)對(duì)應(yīng)終端的鍵盤狸相、標(biāo)準(zhǔn)輸出文件(stdout)和標(biāo)準(zhǔn)錯(cuò)誤輸出文件(stderr),后兩個(gè)文件都對(duì)應(yīng)被重定向到終端的屏幕捐川,以便我們能直接看到輸出內(nèi)容脓鹃。進(jìn)程將從標(biāo)準(zhǔn)輸入文件中得到輸入數(shù)據(jù),將正常輸出數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出文件属拾,而將錯(cuò)誤信息送到標(biāo)準(zhǔn)錯(cuò)誤文件中将谊。
cp /etc/passwd passwd
cat passwd
加上 -n 參數(shù)顯示行號(hào):
cat -n passwd
nl 命令冷溶,添加行號(hào)并打印渐白,這是個(gè)比 cat -n 更專業(yè)的行號(hào)打印命令。
-b : 指定添加行號(hào)的方式逞频,主要有兩種:
-b a:表示無(wú)論是否為空行纯衍,同樣列出行號(hào)("cat -n"就是這種方式)
-b t:只列出非空行的編號(hào)并列出(默認(rèn)為這種方式)
-n : 設(shè)置行號(hào)的樣式,主要有三種:
-n ln:在行號(hào)字段最左端顯示
-n rn:在行號(hào)字段最右邊顯示苗胀,且不加 0
-n rz:在行號(hào)字段最右邊顯示襟诸,且加 0
-w : 行號(hào)字段占用的位數(shù)(默認(rèn)為 6 位)
使用 more 和 less 命令分頁(yè)查看文件
more 和 less 就是天生用來(lái)"閱讀"一個(gè)文件的內(nèi)容的,比如說(shuō) man 手冊(cè)內(nèi)部就是使用的 less 來(lái)顯示內(nèi)容基协。其中 more 命令比較簡(jiǎn)單歌亲,只能向一個(gè)方向滾動(dòng),而 less 為基于 more 和 vi (一個(gè)強(qiáng)大的編輯器澜驮,我們有單獨(dú)的課程來(lái)讓你學(xué)習(xí))開發(fā)陷揪,功能更強(qiáng)大。less 的使用基本和 more 一致杂穷。
more passwd
打開后默認(rèn)只顯示一屏內(nèi)容悍缠,終端底部顯示當(dāng)前閱讀的進(jìn)度∧土浚可以使用 Enter 鍵向下滾動(dòng)一行飞蚓,使用 Space 鍵向下滾動(dòng)一屏,按下 h 顯示幫助廊蜒,q 退出趴拧。
使用 head 和 tail 命令查看文件
只查看文件的頭幾行(默認(rèn)為 10 行,不足 10 行則顯示全部)和尾幾行山叮。
tail /etc/passwd
甚至更直接的只看一行八堡, 加上 -n 參數(shù),后面緊跟行數(shù):
tail -n 1 /etc/passwd
參數(shù) -f聘芜,這個(gè)參數(shù)可以實(shí)現(xiàn)不停地讀取某個(gè)文件的內(nèi)容并顯示兄渺。這可以讓我們動(dòng)態(tài)查看日志,達(dá)到實(shí)時(shí)監(jiān)視的目的汰现。
查看文件類型
可以使用 file 命令查看文件的類型:
file /bin/ls
說(shuō)明這是一個(gè)可執(zhí)行文件挂谍,運(yùn)行在 64 位平臺(tái)叔壤,并使用了動(dòng)態(tài)鏈接文件(共享庫(kù))。
與 Windows 不同的是口叙,如果你新建了一個(gè) shiyanlou.txt 文件炼绘,Windows 會(huì)自動(dòng)把它識(shí)別為文本文件,而 file 命令會(huì)識(shí)別為一個(gè)空文件妄田。
編輯文件
在 Linux 下面編輯文件通常我們會(huì)直接使用專門的命令行編輯器比如(emacs俺亮,vim,nano)疟呐。
快速地入門脚曾,可以直接使用 Linux 內(nèi)部的 vim 學(xué)習(xí)教程,輸入如下命令即可開始:
vimtutor
環(huán)境變量與文件查找
環(huán)境變量
所謂變量就是計(jì)算機(jī)中用于記錄一個(gè)值(不一定是數(shù)值启具,也可以是字符或字符串)的符號(hào)本讥,而這些符號(hào)將用于不同的運(yùn)算處理中。通常變量與值是一對(duì)一的關(guān)系鲁冯,可以通過(guò)表達(dá)式讀取它的值并賦值給其它變量拷沸,也可以直接指定數(shù)值賦值給任意變量。
變量的作用域即變量的有效范圍(比如一個(gè)函數(shù)中薯演、一個(gè)源文件中或者全局范圍)撞芍,在該范圍內(nèi)只能有一個(gè)同名變量。一旦離開則該變量無(wú)效跨扮,如同不存在這個(gè)變量一般序无。
使用 declare 命令創(chuàng)建一個(gè)變量名為 tmp 的變量:
declare tmp
也可以不用 declare 預(yù)聲明一個(gè)變量,直接即用即創(chuàng)建好港,這里只是告訴你 declare 的作用愉镰,這在創(chuàng)建其它指定類型的變量(如數(shù)組)時(shí)會(huì)用到。
使用 = 號(hào)賦值運(yùn)算符钧汹,將變量 tmp 賦值為 shiyanlou丈探。Shell 中的賦值操作,= 兩邊不可以輸入空格拔莱,否則會(huì)報(bào)錯(cuò)碗降。
讀取變量的值,使用 echo 命令和 符號(hào)用于表示引用一個(gè)變量的值):
echo $tmp
并不是任何形式的變量名都是可用的塘秦,變量名只能是英文字母讼渊、數(shù)字或者下劃線,且不能以數(shù)字作為開頭尊剔。
環(huán)境變量的作用域比自定義變量的要大爪幻,如 Shell 的環(huán)境變量作用于自身和它的子進(jìn)程。在所有的 UNIX 和類 UNIX 系統(tǒng)中,每個(gè)進(jìn)程都有其各自的環(huán)境變量設(shè)置挨稿,且默認(rèn)情況下仇轻,當(dāng)一個(gè)進(jìn)程被創(chuàng)建時(shí),除了創(chuàng)建過(guò)程中明確指定的話奶甘,它將繼承其父進(jìn)程的絕大部分環(huán)境設(shè)置篷店。Shell 程序也作為一個(gè)進(jìn)程運(yùn)行在操作系統(tǒng)之上,而我們?cè)?Shell 中運(yùn)行的大部分命令都將以 Shell 的子進(jìn)程的方式運(yùn)行臭家。
當(dāng)前 Shell 進(jìn)程私有用戶自定義變量疲陕,如上面我們創(chuàng)建的 tmp 變量,只在當(dāng)前 Shell 中有效钉赁。Shell 本身內(nèi)建的變量蹄殃。從自定義變量導(dǎo)出的環(huán)境變量。
temp=shiyanlou
export temp_env=shiyanlou
env|sort>env.txt
export|sort>export.txt
set|sort>set.txt
vimdiff env.txt export.txt set.txt
關(guān)于哪些變量是環(huán)境變量橄霉,可以簡(jiǎn)單地理解成在當(dāng)前進(jìn)程的子進(jìn)程有效則為環(huán)境變量窃爷,否則不是(有些人也將所有變量統(tǒng)稱為環(huán)境變量邑蒋,只是以全局環(huán)境變量和局部環(huán)境變量進(jìn)行區(qū)分姓蜂,我們只要理解它們的實(shí)質(zhì)區(qū)別即可)。為了與普通變量區(qū)分医吊,通常我們習(xí)慣將環(huán)境變量名設(shè)為大寫钱慢。
按變量的生存周期來(lái)劃分,Linux 變量可分為兩類:
永久的:需要修改配置文件束莫,變量永久生效;
臨時(shí)的:使用 export 命令行聲明即可僵腺,變量在關(guān)閉 shell 時(shí)失效。
/etc/bashrc(有的 Linux 沒有這個(gè)文件) 和 /etc/profile ,它們分別存放的是 shell 變量和環(huán)境變量锦庸。還有要注意區(qū)別的是每個(gè)用戶目錄下的一個(gè)隱藏文件:
cd /home/shiyanlou
ls -a
.profile 只對(duì)當(dāng)前用戶永久生效庞钢。因?yàn)樗4嬖诋?dāng)前用戶的 Home 目錄下媳维,當(dāng)切換用戶時(shí)磺芭,工作目錄可能一并被切換到對(duì)應(yīng)的目錄中赁炎,這個(gè)文件就無(wú)法生效安皱。而寫在 /etc/profile 里面的是對(duì)所有用戶永久生效诡挂,所以如果想要添加一個(gè)永久生效的環(huán)境變量,只需要打開 /etc/profile蛔添,在最后加上你想添加的環(huán)境變量就好啦放棒。
命令的查找路徑與順序
命令是通過(guò)環(huán)境變量 PATH 來(lái)進(jìn)行搜索的姻报。
echo $PATH
通常這一類目錄下放的都是可執(zhí)行文件,當(dāng)我們?cè)?Shell 中執(zhí)行一個(gè)命令時(shí)间螟,系統(tǒng)就會(huì)按照 PATH 中設(shè)定的路徑按照順序依次到目錄中去查找吴旋,如果存在同名的命令损肛,則執(zhí)行先找到的那個(gè)。
cd /home/shiyanlou
touch hello_shell.sh
vim hello_shell.sh
#!/bin/bash
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0
chmod 755 hello_shell.sh
添加自定義路徑到“ PATH ”環(huán)境變量
我們可以這樣添加自定義路徑:
PATH=$PATH:/home/shiyanlou/mybin
這里一定要使用絕對(duì)路徑荣瑟。
在每個(gè)用戶的 home 目錄中有一個(gè) Shell 每次啟動(dòng)時(shí)會(huì)默認(rèn)執(zhí)行一個(gè)配置腳本笆焰,以初始化環(huán)境粟焊,包括添加一些用戶自定義環(huán)境變量等等透典。
在每個(gè)用戶的 home 目錄中有一個(gè) Shell 每次啟動(dòng)時(shí)會(huì)默認(rèn)執(zhí)行一個(gè)配置腳本漩氨,以初始化環(huán)境渠牲,包括添加一些用戶自定義環(huán)境變量等等,配置文件為 .bashrc泽铛。它們?cè)?etc 下還都有一個(gè)或多個(gè)全局的配置文件,不過(guò)我們一般只修改用戶目錄下的配置文件厉斟。
cat /etc/shells
我們可以簡(jiǎn)單地使用下面命令直接添加內(nèi)容到 .bashrc 中:
echo "PATH=$PATH:/home/shiyanlou/mybin" >> .bashrc
>> 表示將標(biāo)準(zhǔn)輸出以追加的方式重定向到一個(gè)文件中究飞,注意前面用到的 > 是以覆蓋的方式重定向到一個(gè)文件中敏晤,使用的時(shí)候一定要注意分辨韵洋。在指定文件不存在的情況下都會(huì)創(chuàng)建新的文件队腐。
修改和刪除已有變量
變量的修改有以下幾種方式:
比如我們可以修改前面添加到 PATH 的環(huán)境變量荸型,將添加的 mybin 目錄從環(huán)境變量里刪除。為了避免操作失誤導(dǎo)致命令找不到骤宣,我們先將 PATH 賦值給一個(gè)新的自定義變量 mypath:
echo $mypath
mypath=${mypath%/home/shiyanlou/mybin}
mypath=${mypath%*/mybin}
可以使用 unset 命令刪除一個(gè)環(huán)境變量:
unset mypath
如何讓環(huán)境變量立即生效
可以使用 source 命令來(lái)讓其立即生效
source .bashrc
source 命令還有一個(gè)別名就是 .锰霜,上面的命令如果替換成 . 的方式就該是:
. .bashrc
在使用 . 的時(shí)候,需要注意與表示當(dāng)前路徑的那個(gè)點(diǎn)區(qū)分開桐早。
搜索文件
與搜索相關(guān)的命令常用的有 whereis癣缅,which,find 和 locate哄酝。
whereis 簡(jiǎn)單快速
whereis who
whereis find
whereis find 找到了三個(gè)路徑友存,兩個(gè)可執(zhí)行文件路徑和一個(gè) man 在線幫助文件所在路徑,這個(gè)搜索很快陶衅,因?yàn)樗]有從硬盤中依次查找屡立,而是直接從數(shù)據(jù)庫(kù)中查詢。
whereis 只能搜索二進(jìn)制文件(-b)搀军,man 幫助文件(-m)和源代碼文件(-s)膨俐。如果想要獲得更全面的搜索結(jié)果可以使用 locate 命令。
locate 快而全
使用 locate 命令查找文件也不會(huì)遍歷硬盤罩句,它通過(guò)查詢 /var/lib/mlocate/mlocate.db 數(shù)據(jù)庫(kù)來(lái)檢索信息焚刺。不過(guò)這個(gè)數(shù)據(jù)庫(kù)也不是實(shí)時(shí)更新的,系統(tǒng)會(huì)使用定時(shí)任務(wù)每天自動(dòng)執(zhí)行 updatedb 命令來(lái)更新數(shù)據(jù)庫(kù)门烂。所以有時(shí)候你剛添加的文件乳愉,它可能會(huì)找不到,需要手動(dòng)執(zhí)行一次 updatedb 命令诅福,這個(gè)命令也不是內(nèi)置的命令匾委,在部分環(huán)境中需要手動(dòng)安裝,然后執(zhí)行更新氓润。
sudo apt-get update
sudo apt-get install locate
sudo updatedb
它可以用來(lái)查找指定目錄下的不同文件類型赂乐,如查找 /etc 下所有以 sh 開頭的文件:
locate /etc/sh
它不只是在 /etc 目錄下查找,還會(huì)自動(dòng)遞歸子目錄進(jìn)行查找咖气。
查找 /usr/share/ 下所有 jpg 文件:
locate /usr/share/\*.jpg
要添加 * 號(hào)前面的反斜杠轉(zhuǎn)義挨措,否則會(huì)無(wú)法找到。
如果想只統(tǒng)計(jì)數(shù)目可以加上 -c 參數(shù)崩溪,-i 參數(shù)可以忽略大小寫進(jìn)行查找浅役,whereis 的 -b、-m伶唯、-s 同樣可以使用觉既。
which 小而精
which 本身是 Shell 內(nèi)建的一個(gè)命令,我們通常使用 which 來(lái)確定是否安裝了某個(gè)指定的程序,因?yàn)樗粡?PATH 環(huán)境變量指定的路徑中去搜索命令并且返回第一個(gè)搜索到的結(jié)果瞪讼。也就是說(shuō)钧椰,我們可以看到某個(gè)系統(tǒng)命令是否存在以及執(zhí)行的到底是哪一個(gè)地方的命令。
which man
which nginx
which ping
find 精而細(xì)
find 它不但可以通過(guò)文件類型符欠、文件名進(jìn)行查找而且可以根據(jù)文件的屬性(如文件的時(shí)間戳嫡霞,文件的權(quán)限等)進(jìn)行搜索。
sudo find /etc/ -name interfaces
這條命令表示去 /etc/ 目錄下面 希柿,搜索名字叫做 interfaces 的文件或者目錄诊沪。這是 find 命令最常見的格式, find 的第一個(gè)參數(shù)是要搜索的地方曾撤。命令前面加上 sudo 是因?yàn)閖achin 只是普通用戶端姚,對(duì) /etc 目錄下的很多文件都沒有訪問(wèn)的權(quán)限,如果是 root 用戶則不用使用盾戴。
find 命令的路徑是作為第一個(gè)參數(shù)的寄锐, 基本命令格式為 find [path][option] [action] 。
與時(shí)間相關(guān)的命令參數(shù):
以 -mtime 參數(shù)舉例:
-mtime n:n 為數(shù)字尖啡,表示為在 n 天之前的“一天之內(nèi)”修改過(guò)的文件
-mtime +n:列出在 n 天之前(不包含 n 天本身)被修改過(guò)的文件
-mtime -n:列出在 n 天之內(nèi)(包含 n 天本身)被修改過(guò)的文件
-newer file:file 為一個(gè)已存在的文件橄仆,列出比 file 還要新的文件名
列出 home 目錄中,當(dāng)天(24 小時(shí)之內(nèi))有改動(dòng)的文件:
find ~ -mtime 0
列出用戶家目錄下比 /etc 目錄新的文件:
find ~ -newer /etc
尋找文件
找到 sources.list 文件
sudo find /etc -name sources.list
把文件所有者改為自己(jachin)
sudo chown shiyanlou /etc/apt/sources.list
把權(quán)限修改為僅僅只有自己可讀可寫
sudo chmod 600 /etc/apt/sources.list
文件打包與解壓縮
zip 壓縮打包程序
zip -r -q -o shiyanlou.zip /home/shiyanlou/Desktop
du -h shiyanlou.zip
file shiyanlou.zip
-r 參數(shù)表示遞歸打包包含子目錄的全部?jī)?nèi)容衅斩,-q 參數(shù)表示為安靜模式盆顾,即不向屏幕輸出信息,-o畏梆,表示輸出文件您宪,需在其后緊跟打包輸出文件名。后面使用 du 命令查看打包后文件的大小奠涌。
設(shè)置壓縮級(jí)別為 9 和 1(9 最大宪巨,1 最小)溜畅,重新打包:
zip -r -9 -q -o shiyanlou_9.zip /home/shiyanlou/Desktop -x ~/*.zip
zip -r -1 -q -o shiyanlou_1.zip /home/shiyanlou/Desktop -x ~/*.zip
1 表示最快壓縮但體積大捏卓,9 表示體積最小但耗時(shí)最久。最后那個(gè) -x 是為了排除我們上一次創(chuàng)建的 zip 文件慈格,否則又會(huì)被打包進(jìn)這一次的壓縮文件中怠晴,注意:這里只能使用絕對(duì)路徑,否則不起作用浴捆。
再用 du 命令分別查看默認(rèn)壓縮級(jí)別蒜田、最低、最高壓縮級(jí)別及未壓縮的文件的大醒⌒骸:
du -h -d 0 *.zip ~ | sort
-h冲粤, --human-readable
-d美莫, --max-depth(所查看文件的深度)
使用 -e 參數(shù)可以創(chuàng)建加密壓縮包:
zip -r -e -o shiyanlou_encryption.zip /home/shiyanlou/Desktop
如果你想讓你在 Linux 創(chuàng)建的 zip 壓縮文件在 Windows 上解壓后沒有任何問(wèn)題,那么你還需要對(duì)命令做一些修改:
zip -r -l -o shiyanlou.zip /home/shiyanlou/Desktop
加上 -l 參數(shù)將 LF(換行) 轉(zhuǎn)換為 CR+LF(回車+換行) 來(lái)達(dá)到以上目的色解。
使用 unzip 命令解壓縮 zip 文件
unzip shiyanlou.zip
使用安靜模式茂嗓,將文件解壓到指定目錄:
unzip -q shiyanlou.zip -d ziptest
指定目錄不存在餐茵,將會(huì)自動(dòng)創(chuàng)建科阎。如果你不想解壓只想查看壓縮包的內(nèi)容你可以使用 -l 參數(shù):
unzip -l shiyanlou.zip
使用 unzip 解壓文件時(shí)我們同樣應(yīng)該注意兼容問(wèn)題,不過(guò)這里我們關(guān)心的不再是上面的問(wèn)題忿族,而是中文編碼的問(wèn)題锣笨,通常 Windows 系統(tǒng)上面創(chuàng)建的壓縮文件,如果有有包含中文的文檔或以中文作為文件名的文件時(shí)默認(rèn)會(huì)采用 GBK 或其它編碼道批,而 Linux 上面默認(rèn)使用的是 UTF-8 編碼错英,如果不加任何處理,直接解壓的話可能會(huì)出現(xiàn)中文亂碼的問(wèn)題(有時(shí)候它會(huì)自動(dòng)幫你處理)隆豹,為了解決這個(gè)問(wèn)題椭岩,我們可以在解壓時(shí)指定編碼類型。
使用 -O(英文字母璃赡,大寫 o)參數(shù)指定編碼類型:
unzip -O GBK 中文壓縮文件.zip
tar 打包工具
tar 原本只是一個(gè)打包工具判哥,只是同時(shí)還是實(shí)現(xiàn)了對(duì) 7z、gzip碉考、xz塌计、bzip2 等工具的支持,這些壓縮工具本身只能實(shí)現(xiàn)對(duì)文件或目錄(單獨(dú)壓縮目錄中的文件)的壓縮侯谁,沒有實(shí)現(xiàn)對(duì)文件的打包壓縮锌仅,所以我們也無(wú)需再單獨(dú)去學(xué)習(xí)其他幾個(gè)工具,tar 的解壓和壓縮都是同一個(gè)命令墙贱,只需參數(shù)不同热芹。
tar -P -cf shiyanlou.tar /home/shiyanlou/Desktop
P 保留絕對(duì)路徑符,-c 表示創(chuàng)建一個(gè) tar 包文件惨撇,-f 用于指定創(chuàng)建的文件名伊脓,注意文件名必須緊跟在 -f 參數(shù)之后,還可以加上 -v 參數(shù)以可視的的方式輸出打包的文件串纺。
解包一個(gè)文件(-x 參數(shù))到指定路徑的已存在目錄(-C 參數(shù)):
mkdir tardir
tar -xf shiyanlou.tar -C tardir
只查看不解包文件 -t 參數(shù):
tar -tf shiyanlou.tar
保留文件屬性和跟隨鏈接(符號(hào)鏈接或軟鏈接)丽旅,有時(shí)候我們使用 tar 備份文件當(dāng)你在其他主機(jī)還原時(shí)希望保留文件的屬性(-p 參數(shù))和備份鏈接指向的源文件而不是鏈接本身(-h 參數(shù)):
tar -cphf etc.tar /etc
在創(chuàng)建 tar 文件的基礎(chǔ)上添加 -z 參數(shù),使用 gzip 來(lái)壓縮文件:
tar -czf shiyanlou.tar.gz /home/shiyanlou/Desktop
解壓 *.tar.gz 文件:
tar -xzf shiyanlou.tar.gz
要使用其它的壓縮工具創(chuàng)建或解壓相應(yīng)文件只需要更改一個(gè)參數(shù)即可:
文件系統(tǒng)操作與磁盤管理
查看磁盤和目錄的容量
df
物理主機(jī)上的 /dev/sda1 是對(duì)應(yīng)著主機(jī)硬盤的分區(qū)纺棺,后面的數(shù)字表示分區(qū)號(hào)榄笙,數(shù)字前面的字母 a 表示第幾塊硬盤(也可能是可移動(dòng)磁盤),你如果主機(jī)上有多塊硬盤則可能還會(huì)出現(xiàn) /dev/sdb祷蝌,/dev/sdc 這些磁盤設(shè)備都會(huì)在 /dev 目錄下以文件的存在形式茅撞。
1K-blocks示以磁盤塊大小的方式顯示容量,后面為相應(yīng)的以塊大小表示的已用和可用容量。
df -h
使用 du 命令查看目錄的容量
du # 默認(rèn)同樣以塊的大小展示
du -h # 加上 `-h` 參數(shù)米丘,以更易讀的方式展示
du -h -d 0 ~ # 只查看 1 級(jí)目錄的信息
du -h -d 1 ~ # 查看 2 級(jí)
du -h # 同 --human-readable 以 K剑令,M,G 為單位拄查,提高信息的可讀性吁津。
du -a # 同 --all 顯示目錄中所有文件的大小。
du -s # 同 --summarize 僅顯示總計(jì)堕扶,只列出最后加總的值碍脏。
簡(jiǎn)單的磁盤管理
創(chuàng)建虛擬磁盤
dd 命令用于轉(zhuǎn)換和復(fù)制文件,不過(guò)它的復(fù)制不同于 cp稍算。在 Linux 上典尾,硬件的設(shè)備驅(qū)動(dòng)(如硬盤)和特殊設(shè)備文件(如 /dev/zero 和 /dev/random)都像普通文件一樣,只是在各自的驅(qū)動(dòng)程序中實(shí)現(xiàn)了對(duì)應(yīng)的功能糊探,dd 也可以讀取文件或?qū)懭脒@些文件钾埂。dd 也可以用在備份硬件的引導(dǎo)扇區(qū)、獲取一定數(shù)量的隨機(jī)數(shù)據(jù)或者空數(shù)據(jù)等任務(wù)中科平。dd 程序也可以在復(fù)制時(shí)處理數(shù)據(jù)褥紫,例如轉(zhuǎn)換字節(jié)序、或在 ASCII 與 EBCDIC 編碼間互換匠抗。dd 默認(rèn)從標(biāo)準(zhǔn)輸入中讀取故源,并寫入到標(biāo)準(zhǔn)輸出中,但可以用選項(xiàng) if(input file汞贸,輸入文件)和 of(output file绳军,輸出文件)改變。
用 dd 命令從標(biāo)準(zhǔn)輸入讀入用戶的輸入到標(biāo)準(zhǔn)輸出或者一個(gè)文件中:
root@ubuntu:/home/jachin# dd of=test bs=10 count=1
hello shiyanlou
1+0 records in
1+0 records out
10 bytes copied, 9.89634 s, 0.0 kB/s
root@ubuntu:/home/jachin# anlou
anlou: command not found
root@ubuntu:/home/jachin# du -b test
10 test
root@ubuntu:/home/jachin# cat test
hello shiyroot@ubuntu:/home/jachin#
上述命令從標(biāo)準(zhǔn)輸入設(shè)備讀入用戶輸入(缺省值矢腻,所以可省略)然后輸出到 test 文件门驾,bs(block size)用于指定塊大小(缺省單位為 Byte多柑,也可為其指定如 K奶是,M,G 等單位)竣灌,count 用于指定塊數(shù)量聂沙。指定只讀取總共 10 個(gè)字節(jié)的數(shù)據(jù),當(dāng)我輸入了 hello shiyanlou 之后加上空格回車總共 16 個(gè)字節(jié)(一個(gè)英文字符占一個(gè)字節(jié))內(nèi)容初嘹,顯然超過(guò)了設(shè)定大小及汉。使用 du 和 cat 10 個(gè)字節(jié),而其他的多余輸入將被截取并保留在標(biāo)準(zhǔn)輸入屯烦。
將輸出的英文字符轉(zhuǎn)換為大寫再寫入文件:
root@ubuntu:/home/jachin# dd if=/dev/stdin of=test bs=10 count=1 conv=ucase
shiyanlou
1+0 records in
1+0 records out
10 bytes copied, 10.4515 s, 0.0 kB/s
root@ubuntu:/home/jachin# cat test
SHIYANLOU
從 /dev/zero 設(shè)備創(chuàng)建一個(gè)容量為 256M 的空文件:
root@ubuntu:/home/jachin# dd if=/dev/zero of=virtual.img bs=1M count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 10.3474 s, 25.9 MB/s
root@ubuntu:/home/jachin# du -h virtual.img
256M virtual.img
將我們的虛擬磁盤鏡像格式化為 ext4 文件系統(tǒng):
root@ubuntu:/home/jachin# mkfs.ext4 virtual.img
mke2fs 1.44.1 (24-Mar-2018)
Discarding device blocks: done
Creating filesystem with 262144 1k blocks and 65536 inodes
Filesystem UUID: eb7c8b89-67b5-4246-88a9-87527d8119bb
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
可以看到實(shí)際 mkfs.ext4 是使用 mke2fs 來(lái)完成格式化工作的坷随。
用戶在 Linux/UNIX 的機(jī)器上打開一個(gè)文件以前房铭,包含該文件的文件系統(tǒng)必須先進(jìn)行掛載的動(dòng)作,此時(shí)用戶要對(duì)該文件系統(tǒng)執(zhí)行 mount 的指令以進(jìn)行掛載温眉。該指令通常是使用在 USB 或其他可移除存儲(chǔ)設(shè)備上缸匪,而根目錄則需要始終保持掛載的狀態(tài)。又因?yàn)?Linux/UNIX 文件系統(tǒng)可以對(duì)應(yīng)一個(gè)文件而不一定要是硬件設(shè)備类溢,所以可以掛載一個(gè)包含文件系統(tǒng)的文件到目錄樹凌蔬。
Linux/UNIX 命令行的 mount 指令是告訴操作系統(tǒng),對(duì)應(yīng)的文件系統(tǒng)已經(jīng)準(zhǔn)備好豌骏,可以使用了龟梦,而該文件系統(tǒng)會(huì)對(duì)應(yīng)到一個(gè)特定的點(diǎn)(稱為掛載點(diǎn))。掛載好的文件窃躲、目錄、設(shè)備以及特殊文件即可提供用戶使用钦睡。
mount
輸出的結(jié)果中每一行表示一個(gè)設(shè)備或虛擬設(shè)備蒂窒,每一行最前面是設(shè)備名,然后是 on 后面是掛載點(diǎn)荞怒,type 后面表示文件系統(tǒng)類型洒琢,再后面是掛載選項(xiàng)(比如可以在掛載時(shí)設(shè)定以只讀方式掛載等等)。
掛載我們創(chuàng)建的虛擬磁盤鏡像到 /mnt 目錄:
mount -o loop -t ext4 virtual.img /mnt
# 也可以省略掛載類型褐桌,很多時(shí)候 mount 會(huì)自動(dòng)識(shí)別
# 以只讀方式掛載
mount -o loop --ro virtual.img /mnt
# 或者 mount -o loop,ro virtual.img /mnt
使用 umount 命令卸載已掛載磁盤
umount /mnt/
在類 UNIX 系統(tǒng)中典勇,/dev/loop(或稱 vnd (vnode disk)谜洽、lofi(循環(huán)文件接口))是一種偽設(shè)備,這種設(shè)備使得文件可以如同塊設(shè)備一般被訪問(wèn)。
在使用之前板祝,循環(huán)設(shè)備必須與現(xiàn)存文件系統(tǒng)上的文件相關(guān)聯(lián)。這種關(guān)聯(lián)將提供給用戶一個(gè)應(yīng)用程序接口顾稀,接口將允許文件視為塊特殊文件(參見設(shè)備文件系統(tǒng))使用博肋。因此,如果文件中包含一個(gè)完整的文件系統(tǒng)赃春,那么這個(gè)文件就能如同磁盤設(shè)備一般被掛載愉择。
這種設(shè)備文件經(jīng)常被用于光盤或是磁盤鏡像。通過(guò)循環(huán)掛載來(lái)掛載包含文件系統(tǒng)的文件织中,便使處在這個(gè)文件系統(tǒng)中的文件得以被訪問(wèn)锥涕。這些文件將出現(xiàn)在掛載點(diǎn)目錄。如果掛載目錄中本身有文件狭吼,這些文件在掛載后將被禁止使用层坠。
# 查看硬盤分區(qū)表信息
sudo fdisk -l
輸出結(jié)果中開頭顯示了我主機(jī)上的磁盤的一些信息,包括容量扇區(qū)數(shù)搏嗡,扇區(qū)大小窿春,I/O 大小等信息拉一。
/dev/sda1,/dev/sda2 為主分區(qū)分別安裝了 Windows 和 Linux 操作系統(tǒng)旧乞,/dev/sda3 為交換分區(qū)(可以理解為虛擬內(nèi)存)蔚润,/dev/sda4 為擴(kuò)展分區(qū)其中包含 /dev/sda5,/dev/sda6尺栖,/dev/sda7嫡纠,/dev/sda8 四個(gè)邏輯分區(qū),因?yàn)橹鳈C(jī)上有幾個(gè)分區(qū)之間有空隙延赌,沒有對(duì)齊邊界扇區(qū)除盏,所以分區(qū)之間不是完全連續(xù)的。
# 進(jìn)入磁盤分區(qū)模式
sudo fdisk virtual.img
在進(jìn)行操作前我們首先應(yīng)先規(guī)劃好我們的分區(qū)方案挫以,這里我將在使用 128M(可用 127M 左右)的虛擬磁盤鏡像創(chuàng)建一個(gè) 30M 的主分區(qū)剩余部分為擴(kuò)展分區(qū)包含 2 個(gè)大約 45M 的邏輯分區(qū)者蠕。
操作完成后輸入 p 查看結(jié)果如下:
使用 losetup 命令建立鏡像與回環(huán)設(shè)備的關(guān)聯(lián)
sudo losetup /dev/loop0 virtual.img
# 如果提示設(shè)備忙你也可以使用其它的回環(huán)設(shè)備,"ls /dev/loop*"參看所有回環(huán)設(shè)備
# 解除設(shè)備關(guān)聯(lián)
sudo losetup -d /dev/loop0
然后再使用 mkfs 格式化各分區(qū)(前面我們是格式化整個(gè)虛擬磁盤鏡像文件或磁盤)掐松,不過(guò)格式化之前踱侣,我們還要為各分區(qū)建立虛擬設(shè)備的映射。
sudo apt-get install kpartx
sudo kpartx -av /dev/loop0
# 取消映射
sudo kpartx -dv /dev/loop0
接著再是格式化大磺,我們將其全部格式化為 ext4:
sudo mkfs.ext4 -q /dev/mapper/loop0p1
sudo mkfs.ext4 -q /dev/mapper/loop0p5
sudo mkfs.ext4 -q /dev/mapper/loop0p6
格式化完成后在 /media 目錄下新建四個(gè)空目錄用于掛載虛擬磁盤:
mkdir -p /media/virtualdisk_{1..3}
# 掛載磁盤分區(qū)
sudo mount /dev/mapper/loop0p1 /media/virtualdisk_1
sudo mount /dev/mapper/loop0p5 /media/virtualdisk_2
sudo mount /dev/mapper/loop0p6 /media/virtualdisk_3
# 卸載磁盤分區(qū)
sudo umount /dev/mapper/loop0p1
sudo umount /dev/mapper/loop0p5
sudo umount /dev/mapper/loop0p6
df -h
Linux下的幫助命令
內(nèi)建命令與外部命令
內(nèi)建命令實(shí)際上是 shell 程序的一部分抡句,其中包含的是一些比較簡(jiǎn)單的 Linux 系統(tǒng)命令,這些命令是寫在 bash 源碼的 builtins 里面的杠愧,由 shell 程序識(shí)別并在 shell 程序內(nèi)部完成運(yùn)行待榔,通常在 Linux 系統(tǒng)加載運(yùn)行時(shí) shell 就被加載并駐留在系統(tǒng)內(nèi)存中。而且解析內(nèi)部命令 shell 不需要?jiǎng)?chuàng)建子進(jìn)程流济,因此其執(zhí)行速度比外部命令快锐锣。比如:history、cd袭灯、exit 等等刺下。
外部命令是 Linux 系統(tǒng)中的實(shí)用程序部分,因?yàn)閷?shí)用程序的功能通常都比較強(qiáng)大稽荧,所以其包含的程序量也會(huì)很大橘茉,在系統(tǒng)加載時(shí)并不隨系統(tǒng)一起被加載到內(nèi)存中,而是在需要時(shí)才將其調(diào)入內(nèi)存姨丈。雖然其不包含在 shell 中畅卓,但是其命令執(zhí)行過(guò)程是由 shell 程序控制的。外部命令是在 Bash 之外額外安裝的蟋恬,通常放在/bin翁潘,/usr/bin,/sbin歼争,/usr/sbin 等等拜马。比如:ls、vi 等。
簡(jiǎn)單來(lái)說(shuō)就是:一個(gè)是天生自帶的天賦技能崩侠,一個(gè)是后天得來(lái)的附加技能裸删。我們可以使用 type 命令來(lái)區(qū)分命令是內(nèi)建的還是外部的专甩。
type exit
type vim
type ls
help 命令
help 命令是用于顯示 shell 內(nèi)建命令的簡(jiǎn)要幫助信息,幫助信息中顯示有該命令的簡(jiǎn)要說(shuō)明以及一些參數(shù)的使用以及說(shuō)明。
外部命令基本上都有一個(gè)參數(shù) --help衷快,這樣就可以得到相應(yīng)的幫助宙橱,看到你想要的東西了。
ls --help
man 命令
man ls
man 沒有內(nèi)建與外部命令的區(qū)分蘸拔,因?yàn)?man 工具是顯示系統(tǒng)手冊(cè)頁(yè)中的內(nèi)容师郑,也就是一本電子版的字典,這些內(nèi)容大多數(shù)都是對(duì)命令的解釋信息调窍,還有一些相關(guān)的描述宝冕。通過(guò)查看系統(tǒng)文檔中的 man 也可以得到程序的更多相關(guān)信息和 Linux 的更多特性。
可以通過(guò) pgup 與 pgdn 或者上下鍵來(lái)上下翻看邓萨,可以按 q 退出當(dāng)前頁(yè)面猬仁。
info 命令
info ls
是 GNU 的超文本幫助系統(tǒng),能夠更完整的顯示出 GNU 信息先誉。info 工具可顯示更完整的 GNU 工具信息。
Linux任務(wù)計(jì)劃crontab
crontab 命令從輸入設(shè)備讀取指令的烁,并將其存放于 crontab 文件中褐耳,以供之后讀取和執(zhí)行。通常渴庆,crontab 儲(chǔ)存的指令被守護(hù)進(jìn)程激活铃芦,crond 為其守護(hù)進(jìn)程,crond 常常在后臺(tái)運(yùn)行襟雷,每一分鐘會(huì)檢查一次是否有預(yù)定的作業(yè)需要執(zhí)行刃滓。
通過(guò) crontab 命令,我們可以在固定的間隔時(shí)間執(zhí)行指定的系統(tǒng)指令或 shell 腳本耸弄。時(shí)間間隔的單位可以是分鐘咧虎、小時(shí)、日计呈、月砰诵、周的任意組合征唬。
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
啟動(dòng) rsyslog,以便我們可以通過(guò)日志中的信息來(lái)了解我們的任務(wù)是否真正的被執(zhí)行了茁彭。
sudo service rsyslog start
sudo cron -f &
第一次啟動(dòng)會(huì)出現(xiàn)這樣一個(gè)畫面总寒,這是讓我們選擇編輯的工具,選擇第二個(gè)基本的 vim 就可以了理肺。
在文檔的最后一排加上這樣一排命令摄闸,該任務(wù)是每分鐘我們會(huì)在/home/shiyanlou 目錄下創(chuàng)建一個(gè)以當(dāng)前的年月日時(shí)分秒為名字的空白文件
*/1 * * * * touch /home/jachin/$(date +\%Y\%m\%d\%H\%M\%S)
“ % ” 在 crontab 文件中,有結(jié)束命令行妹萨、換行年枕、重定向的作用,前面加 ” \ ” 符號(hào)轉(zhuǎn)義眠副,否則画切,“ % ” 符號(hào)將執(zhí)行其結(jié)束命令行或者換行的作用,并且其后的內(nèi)容會(huì)被做為標(biāo)準(zhǔn)輸入發(fā)送給前面的命令囱怕。
查看我們添加了哪些任務(wù):
crontab -l
雖然我們添加了任務(wù)霍弹,但是如果 cron 的守護(hù)進(jìn)程并沒有啟動(dòng),它根本都不會(huì)監(jiān)測(cè)到有任務(wù)娃弓,當(dāng)然也就不會(huì)幫我們執(zhí)行典格,我們可以通過(guò)以下 2 種方式來(lái)確定我們的 cron 是否成功的在后臺(tái)啟動(dòng),默默的幫我們做事台丛,若是沒有就得執(zhí)行上文準(zhǔn)備中的第二步了耍缴。
ps aux | grep cron
pgrep cron
可以看到任務(wù)在創(chuàng)建之后,執(zhí)行了幾次挽霉,生成了一些文件防嗡,且每分鐘生成一個(gè):
ll
可以查看到執(zhí)行任務(wù)命令之后在日志中的信息反饋:
sudo tail -f /var/log/syslog
當(dāng)我們并不需要這個(gè)任務(wù)的時(shí)候我們可以使用這么一個(gè)命令去刪除任務(wù):
crontab -r
們可以看出我們刪除之后再查看任務(wù)列表,系統(tǒng)已經(jīng)顯示該用戶并沒有任務(wù)侠坎。
crontab -l
每個(gè)用戶使用 crontab -e 添加計(jì)劃任務(wù)蚁趁,都會(huì)在 /var/spool/cron/crontabs 中添加一個(gè)該用戶自己的任務(wù)文檔,這樣目的是為了隔離实胸。
ll /var/spool/cron/crontabs/
如果是系統(tǒng)級(jí)別的定時(shí)任務(wù)他嫡,只需要使用 sudo 編輯 /etc/crontab 文件就可以。
cron 服務(wù)監(jiān)測(cè)時(shí)間最小單位是分鐘庐完,所以 cron 會(huì)每分鐘去讀取一次 /etc/crontab 與 /var/spool/cron/crontabs 里面的內(nèi)容钢属。
在 /etc 目錄下,cron 相關(guān)的目錄有下面幾個(gè):
ll /etc/ | grep cron
/etc/cron.daily门躯,目錄下的腳本會(huì)每天執(zhí)行一次淆党,在每天的 6 點(diǎn) 25 分時(shí)運(yùn)行;
/etc/cron.hourly,目錄下的腳本會(huì)每個(gè)小時(shí)執(zhí)行一次宁否,在每小時(shí)的 17 分鐘時(shí)運(yùn)行窒升;
/etc/cron.monthly,目錄下的腳本會(huì)每月執(zhí)行一次慕匠,在每月 1 號(hào)的 6 點(diǎn) 52 分時(shí)運(yùn)行饱须;
/etc/cron.weekly,目錄下的腳本會(huì)每周執(zhí)行一次台谊,在每周第七天的 6 點(diǎn) 47 分時(shí)運(yùn)行蓉媳;
系統(tǒng)默認(rèn)執(zhí)行時(shí)間可以根據(jù)需求進(jìn)行修改。
備份日志
為jachin 用戶添加計(jì)劃任務(wù)
每天凌晨 3 點(diǎn)的時(shí)候定時(shí)備份 alternatives.log 到 /home/jachin/tmp/ 目錄
命名格式為 年-月-日锅铅,比如今天是 2017 年 4 月 1 日酪呻,那么文件名為 2017-04-01
sudo cron -f &
crontab -e # 添加
0 3 * * * sudo rm /home/jachin/tmp/*
0 3 * * * sudo cp /var/log/alternatives.log
/home/jachin/tmp/$(date +\%Y-\%m-\%d)
命令執(zhí)行順序控制與管道
順序執(zhí)行多條命令
簡(jiǎn)單的順序執(zhí)行你可以使用 ; 來(lái)完成。
有選擇的執(zhí)行命令
比如上一條命令執(zhí)行成功才繼續(xù)下一條盐须,或者不成功又該做出其它什么處理玩荠,比如我們使用 which 來(lái)查找是否安裝某個(gè)命令,如果找到就執(zhí)行該命令贼邓,否則什么也不做
which cowsay>/dev/null && cowsay -f head-in ohch~
&& 就是用來(lái)實(shí)現(xiàn)選擇性執(zhí)行的阶冈,它表示如果前面的命令執(zhí)行結(jié)果(不是表示終端輸出的內(nèi)容,而是表示命令執(zhí)行狀態(tài)的結(jié)果)返回 0 則執(zhí)行后面的塑径,否則不執(zhí)行女坑。
shell 中的這兩個(gè)符號(hào)除了也可用于表示邏輯與和或之外,就是可以實(shí)現(xiàn)這里的命令執(zhí)行順序的簡(jiǎn)單控制统舀。|| 在這里就是與 && 相反的控制效果,當(dāng)上一條命令執(zhí)行結(jié)果為 ≠0($?≠0) 時(shí)則執(zhí)行它后面的命令:
which cowsay>/dev/null || echo "cowsay has not been install, please run 'sudo apt-get install cowsay' to install"
which cowsay>/dev/null && echo "exist" || echo "not exist"
管道
管道是一種通信機(jī)制誉简,通常用于進(jìn)程間的通信(也可通過(guò) socket 進(jìn)行網(wǎng)絡(luò)通信)碉就,它表現(xiàn)出來(lái)的形式就是將前面每一個(gè)進(jìn)程的輸出(stdout)直接作為下一個(gè)進(jìn)程的輸入(stdin)闷串。管道又分為匿名管道和具名管道闲勺。我們?cè)谑褂靡恍┻^(guò)濾程序時(shí)經(jīng)常會(huì)用到的就是匿名管道衙耕,在命令行中由 | 分隔符表示,序芦。具名管道簡(jiǎn)單的說(shuō)就是有名字的管道臭杰,通常只會(huì)在源程序中用到具名管道。
查看 /etc 目錄下有哪些文件和目錄谚中,使用 ls 命令來(lái)查看:
ls -al /etc
ls -al /etc | less
** cut 命令渴杆,打印每一行的某一字段**
打印 /etc/passwd 文件中以 : 為分隔符的第 1 個(gè)字段和第 6 個(gè)字段分別表示用戶名和其家目錄:
cut /etc/passwd -d ':' -f 1,6
打印 /etc/passwd 文件中每一行的前 N 個(gè)字符:
# 前五個(gè)(包含第五個(gè))
cut /etc/passwd -c -5
# 前五個(gè)之后的(包含第五個(gè))
cut /etc/passwd -c 5-
# 第五個(gè)
cut /etc/passwd -c 5
# 2 到 5 之間的(包含第五個(gè))
cut /etc/passwd -c 2-5
grep 命令,在文本中或 stdin 中查找匹配字符串
我們搜索/home/jachin目錄下所有包含"jachin"的文本文件宪塔,并顯示出現(xiàn)在文本中的行號(hào):
grep -rnI "jachin" ~
-r 參數(shù)表示遞歸搜索子目錄中的文件磁奖,-n 表示打印匹配項(xiàng)行號(hào),-I 表示忽略二進(jìn)制文件某筐。
也可以在匹配字段中使用正則表達(dá)式:
# 查看環(huán)境變量中以 "yanlou" 結(jié)尾的字符串
export | grep ".*yanlou$"
其中$就表示一行的末尾比搭。
wc 命令,簡(jiǎn)單小巧的計(jì)數(shù)工具
wc 命令用于統(tǒng)計(jì)并輸出一個(gè)文件中行南誊、單詞和字節(jié)的數(shù)目身诺,比如輸出 /etc/passwd 文件的統(tǒng)計(jì)信息:
wc /etc/passwd
# 行數(shù)
wc -l /etc/passwd
# 單詞數(shù)
wc -w /etc/passwd
# 字節(jié)數(shù)
wc -c /etc/passwd
# 字符數(shù)
wc -m /etc/passwd
# 最長(zhǎng)行字節(jié)數(shù)
wc -L /etc/passwd
對(duì)于西文字符來(lái)說(shuō),一個(gè)字符就是一個(gè)字節(jié)抄囚,但對(duì)于中文字符一個(gè)漢字是大于 2 個(gè)字節(jié)的霉赡,具體數(shù)目是由字符編碼決定的。
結(jié)合管道來(lái)操作一下幔托,下面統(tǒng)計(jì) /etc 下面所有目錄數(shù):
ls -dl /etc/*/ | wc -l
sort 排序命令
將輸入按照一定方式排序穴亏,然后再輸出蜂挪,它支持的排序有按字典排序,數(shù)字排序嗓化,按月份排序棠涮,隨機(jī)排序,反轉(zhuǎn)排序刺覆,指定特定字段進(jìn)行排序等等严肪。
默認(rèn)為字典排序:
cat /etc/passwd | sort
反轉(zhuǎn)排序:
cat /etc/passwd | sort -r
按特定字段排序:
cat /etc/passwd | sort -t':' -k 3
-t參數(shù)用于指定字段的分隔符,這里是以":"作為分隔符隅津;-k 字段號(hào)用于指定對(duì)哪一個(gè)字段進(jìn)行排序诬垂。這里/etc/passwd文件的第三個(gè)字段為數(shù)字,默認(rèn)情況下是以字典序排序的伦仍,如果要按照數(shù)字排序就要加上-n參數(shù):
cat /etc/passwd | sort -t':' -k 3 -n
uniq 去重命令
過(guò)濾重復(fù)行
可以使用 history 命令查看最近執(zhí)行過(guò)的命令(實(shí)際為讀取 ${SHELL}_history 文件)结窘,不過(guò)你可能只想查看使用了哪個(gè)命令而不需要知道具體干了什么,那么你可能就會(huì)要想去掉命令后面的參數(shù)然后去掉重復(fù)的命令:
history | cut -c 8- | cut -d ' ' -f 1 | uniq
然后經(jīng)過(guò)層層過(guò)濾充蓝,你會(huì)發(fā)現(xiàn)確是只輸出了執(zhí)行的命令那一列隧枫,不過(guò)去重效果好像不明顯,仔細(xì)看你會(huì)發(fā)現(xiàn)它確實(shí)去重了谓苟,只是不那么明顯官脓,之所以不明顯是因?yàn)?uniq 命令只能去連續(xù)重復(fù)的行,不是全文去重涝焙,所以要達(dá)到預(yù)期效果卑笨,我們先排序:
history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq
# 或者
history | cut -c 8- | cut -d ' ' -f 1 | sort -u
輸出重復(fù)行
# 輸出重復(fù)過(guò)的行(重復(fù)的只輸出一個(gè))及重復(fù)次數(shù)
history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -dc
# 輸出所有重復(fù)的行
history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -D
簡(jiǎn)單的文本處理
tr 命令
tr 命令可以用來(lái)刪除一段文本信息中的某些文字÷刈玻或者將其進(jìn)行轉(zhuǎn)換赤兴。
# 刪除 "hello shiyanlou" 中所有的'o','l'隧哮,'h'
$ echo 'hello shiyanlou' | tr -d 'olh'
# 將"hello" 中的ll桶良,去重為一個(gè)l
$ echo 'hello' | tr -s 'l'
# 將輸入文本,全部轉(zhuǎn)換為大寫或小寫輸出
$ echo 'input some text here' | tr '[:lower:]' '[:upper:]'
# 上面的'[:lower:]' '[:upper:]'你也可以簡(jiǎn)單的寫作'[a-z]' '[A-Z]'沮翔,當(dāng)然反過(guò)來(lái)將大寫變小寫也是可以的
col 命令
col 命令可以將Tab換成對(duì)等數(shù)量的空格鍵陨帆,或反轉(zhuǎn)這個(gè)操作。
# 查看 /etc/protocols 中的不可見字符采蚀,可以看到很多 ^I 疲牵,這其實(shí)就是 Tab 轉(zhuǎn)義成可見字符的符號(hào)
cat -A /etc/protocols
# 使用 col -x 將 /etc/protocols 中的 Tab 轉(zhuǎn)換為空格,然后再使用 cat 查看,你發(fā)現(xiàn) ^I 不見了
cat /etc/protocols | col -x | cat -A
join 命令
這個(gè)命令就是用于將兩個(gè)文件中包含相同內(nèi)容的那一行合并在一起。
# 創(chuàng)建兩個(gè)文件
echo '1 hello' > file1
echo '1 shiyanlou' > file2
join file1 file2
# 將 /etc/passwd 與 /etc/shadow 兩個(gè)文件合并润歉,指定以':'作為分隔符
sudo join -t':' /etc/passwd /etc/shadow
# 將 /etc/passwd 與 /etc/group 兩個(gè)文件合并,指定以':'作為分隔符,分別比對(duì)第4和第3個(gè)字段
sudo join -t':' -1 4 /etc/passwd -2 3 /etc/group
paste 命令
它是在不對(duì)比數(shù)據(jù)的情況下,簡(jiǎn)單地將多個(gè)文件合并一起责静,以Tab隔開袁滥。
echo hello > file1
echo shiyanlou > file2
echo www.shiyanlou.com > file3
paste -d ':' file1 file2 file3
paste -s file1 file2 file3
數(shù)據(jù)流重定向
echo 'hello shiyanlou' > redirect
echo 'www.shiyanlou.com' >> redirect
cat redirect
stdin(標(biāo)準(zhǔn)輸入,對(duì)應(yīng)于你在終端的輸入)灾螃,stdout(標(biāo)準(zhǔn)輸出题翻,對(duì)應(yīng)于終端的輸出),stderr(標(biāo)準(zhǔn)錯(cuò)誤輸出腰鬼,對(duì)應(yīng)于終端的輸出)嵌赠。
文件描述符:文件描述符在形式上是一個(gè)非負(fù)整數(shù)。實(shí)際上熄赡,它是一個(gè)索引值姜挺,指向內(nèi)核為每一個(gè)進(jìn)程所維護(hù)的該進(jìn)程打開文件的記錄表。當(dāng)程序打開一個(gè)現(xiàn)有文件或者創(chuàng)建一個(gè)新文件時(shí)彼硫,內(nèi)核向進(jìn)程返回一個(gè)文件描述符炊豪。在程序設(shè)計(jì)中,一些涉及底層的程序編寫往往會(huì)圍繞著文件描述符展開拧篮。但是文件描述符這一概念往往只適用于 UNIX词渤、Linux 這樣的操作系統(tǒng)。
將 cat 的連續(xù)輸出(heredoc 方式)重定向到一個(gè)文件:
mkdir Documents
cat > Documents/test.c <<EOF
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
EOF
將一個(gè)文件作為命令的輸入串绩,標(biāo)準(zhǔn)輸出作為命令的輸出:
cat Documents/test.c
將 echo 命令通過(guò)管道傳過(guò)來(lái)的數(shù)據(jù)作為 cat 命令的輸入缺虐,將標(biāo)準(zhǔn)輸出作為命令的輸出:
echo 'hi' | cat
將 echo 命令的輸出從默認(rèn)的標(biāo)準(zhǔn)輸出重定向到一個(gè)普通文件:
echo 'hello shiyanlou' > redirect
cat redirect
標(biāo)準(zhǔn)錯(cuò)誤重定向
標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤都被指向偽終端的屏幕顯示,所以我們經(jīng)辰阜玻看到的一個(gè)命令的輸出通常是同時(shí)包含了標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤的結(jié)果的高氮。
# 使用cat 命令同時(shí)讀取兩個(gè)文件,其中一個(gè)存在把篓,另一個(gè)不存在
cat Documents/test.c hello.c
# 你可以看到除了正確輸出了前一個(gè)文件的內(nèi)容纫溃,還在末尾出現(xiàn)了一條錯(cuò)誤信息
# 下面我們將輸出重定向到一個(gè)文件
cat Documents/test.c hello.c > somefile
# 將標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出,再將標(biāo)準(zhǔn)輸出重定向到文件韧掩,注意要將重定向到文件寫到前面
cat Documents/test.c hello.c >somefile 2>&1
# 或者只用bash提供的特殊的重定向符號(hào)"&"將標(biāo)準(zhǔn)錯(cuò)誤和標(biāo)準(zhǔn)輸出同時(shí)重定向到文件
cat Documents/test.c hello.c &>somefilehell
使用 tee 命令同時(shí)重定向到多個(gè)文件
echo 'hello shiyanlou' | tee hello
永久重定向
exec 命令的作用是使用指定的命令替換當(dāng)前的 Shell紊浩,即使用一個(gè)進(jìn)程替換當(dāng)前進(jìn)程,或者指定新的重定向:
# 先開啟一個(gè)子 Shell
sh
# 使用exec替換當(dāng)前進(jìn)程的重定向疗锐,將標(biāo)準(zhǔn)輸出重定向到一個(gè)文件
exec 1>somefile
# 后面你執(zhí)行的命令的輸出都將被重定向到文件中坊谁,直到你退出當(dāng)前子shell,或取消exec的重定向(后面將告訴你怎么做)
ls
exit
cat somefile
創(chuàng)建輸出文件描述符
在 Shell 中有 9 個(gè)文件描述符滑臊。
查看當(dāng)前 Shell 進(jìn)程中打開的文件描述符:
cd /dev/fd/;ls -Al
sh
exec 3>somefile
# 先進(jìn)入目錄口芍,再查看,否則你可能不能得到正確的結(jié)果雇卷,然后再回到上一次的目錄
cd /dev/fd/;ls -Al;cd -
# 注意下面的命令>與&之間不應(yīng)該有空格鬓椭,如果有空格則會(huì)出錯(cuò)
echo "this is test" >&3
cat somefile
exit
關(guān)閉文件描述符
exec 3>&-
cd /dev/fd;ls -Al;cd -
完全屏蔽命令的輸出
在類 UNIX 系統(tǒng)中颠猴,/dev/null,或稱空設(shè)備小染,是一個(gè)特殊的設(shè)備文件翘瓮,它通常被用于丟棄不需要的輸出流,或作為用于輸入流的空文件裤翩,這些操作通常由重定向完成资盅。讀取它則會(huì)立即得到一個(gè) EOF。
屏蔽命令的輸出:
cat Documents/test.c 1>/dev/null 2>&1
使用 xargs 分割參數(shù)列表
xargs 是一條 UNIX 和類 UNIX 操作系統(tǒng)的常用命令踊赠。它的作用是將參數(shù)列表轉(zhuǎn)換成小塊分段傳遞給其他命令呵扛,以避免參數(shù)列表過(guò)長(zhǎng)的問(wèn)題。
這個(gè)命令在有些時(shí)候十分有用筐带,特別是當(dāng)用來(lái)處理產(chǎn)生大量輸出結(jié)果的命令如 find今穿,locate 和 grep 的結(jié)果
cut -d: -f1 < /etc/passwd | sort | xargs echo
將 /etc/passwd 文件按 : 分割取第一個(gè)字段排序后,使用 echo 命令生成一個(gè)列表烫堤。
歷史命令
結(jié)果包含三行內(nèi)容荣赶,每行內(nèi)容都是出現(xiàn)的次數(shù)和命令名稱,如“100 ls”
wget https://labfile.oss.aliyuncs.com/courses/1/data1
cat data1 |cut -c 8-|sort|uniq -dc|sort -rn -k1 |head -3 > /home/shiyanlou/result
正則表達(dá)式基礎(chǔ)
正則表達(dá)式鸽斟,又稱正規(guī)表示式拔创、正規(guī)表示法、正規(guī)表達(dá)式富蓄、規(guī)則表達(dá)式剩燥、常規(guī)表示法(英語(yǔ):Regular Expression,在代碼中常簡(jiǎn)寫為 regex立倍、regexp 或 RE)灭红,計(jì)算機(jī)科學(xué)的一個(gè)概念。正則表達(dá)式使用單個(gè)字符串來(lái)描述口注、匹配一系列符合某個(gè)句法規(guī)則的字符串变擒。在很多文本編輯器里,正則表達(dá)式通常被用來(lái)檢索寝志、替換那些符合某個(gè)模式的文本娇斑。
一個(gè)正則表達(dá)式通常被稱為一個(gè)模式(pattern),為用來(lái)描述或者匹配一系列符合某個(gè)句法規(guī)則的字符串材部。
選擇
| 豎直分隔符表示選擇毫缆,例如 boy|girl 可以匹配 boy 或者 girl。
數(shù)量限定
數(shù)量限定除了 * 還有 + 加號(hào) ? 問(wèn)號(hào)乐导,如果在一個(gè)模式中不加數(shù)量限定符則表示出現(xiàn)一次且僅出現(xiàn)一次:
+ 表示前面的字符必須出現(xiàn)至少一次(1 次或多次)苦丁,例如 goo+gle 可以匹配 gooogle,goooogle 等物臂;
? 表示前面的字符最多出現(xiàn)一次(0 次或 1 次)旺拉,例如产上,colou?r,可以匹配 color 或者 colour;
* 星號(hào)代表前面的字符可以不出現(xiàn)蛾狗,也可以出現(xiàn)一次或者多次(0 次蒂秘、或 1 次、或多次)淘太,例如,0*42 可以匹配 42规丽、042蒲牧、0042、00042 等赌莺。
范圍和優(yōu)先級(jí)
() 圓括號(hào)可以用來(lái)定義模式字符串的范圍和優(yōu)先級(jí)冰抢,這可以簡(jiǎn)單的理解為是否將括號(hào)內(nèi)的模式串作為一個(gè)整體。例如艘狭,gr(a|e)y 等價(jià)于 gray|grey挎扰,(這里體現(xiàn)了優(yōu)先級(jí),豎直分隔符用于選擇 a 或者 e 而不是 gra 和 ey)巢音,(grand)?father 匹配 father 和 grandfather(這里體現(xiàn)了范圍遵倦,? 將圓括號(hào)內(nèi)容作為一個(gè)整體匹配)。
優(yōu)先級(jí)
優(yōu)先級(jí)為從上到下從左到右官撼,依次降低:
regex 的思導(dǎo)圖:
grep
grep 命令用于打印輸出文本中匹配的模式串梧躺,它使用正則表達(dá)式作為模式匹配的條件。
cat <<EOF >test
> shiyanlou
> www.shiyanlou.com
> C
> linux
> dat_struct
> python
> Mysql
> shell
> EOF
grep -c shiyanlou test
grep -i -n c test
grep -v shell test
grep shell test
查找 /etc/group 文件中以 shiyanlou 為開頭的行
grep 'shiyanlou' /etc/group
grep '^shiyanlou' /etc/group
數(shù)量
# 將匹配以'z'開頭以'o'結(jié)尾的所有字符串
echo 'zero\nzo\nzoo' | grep 'z.*o'
# 將匹配以'z'開頭以'o'結(jié)尾傲绣,中間包含一個(gè)任意字符的字符串
echo 'zero\nzo\nzoo' | grep 'z.o'
# 將匹配以'z'開頭掠哥,以任意多個(gè)'o'結(jié)尾的字符串
echo 'zero\nzo\nzoo' | grep 'zo*'
選擇
# grep默認(rèn)是區(qū)分大小寫的,這里將匹配所有的小寫字母
echo '1234\nabcd' | grep '[a-z]'
# 將匹配所有的數(shù)字
echo '1234\nabcd' | grep '[0-9]'
# 將匹配所有的數(shù)字
echo '1234\nabcd' | grep '[[:digit:]]'
# 將匹配所有的小寫字母
echo '1234\nabcd' | grep '[[:lower:]]'
# 將匹配所有的大寫字母
echo '1234\nabcd' | grep '[[:upper:]]'
# 將匹配所有的字母和數(shù)字秃诵,包括0-9续搀,a-z,A-Z
echo '1234\nabcd' | grep '[[:alnum:]]'
# 將匹配所有的字母
echo '1234\nabcd' | grep '[[:alpha:]]'
之所以要使用特殊符號(hào)菠净,是因?yàn)樯厦娴?[a-z] 不是在所有情況下都管用禁舷,這還與主機(jī)當(dāng)前的語(yǔ)系有關(guān),即設(shè)置在 LANG 環(huán)境變量的值嗤练,zh_CN.UTF-8 的話 [a-z]榛了,即為所有小寫字母,其它語(yǔ)系可能是大小寫交替的如煞抬,"a A b B...z Z"霜大,[a-z] 中就可能包含大寫字母。所以在使用 [a-z] 時(shí)請(qǐng)確保當(dāng)前語(yǔ)系的影響革答,使用 [:lower:] 則不會(huì)有這個(gè)問(wèn)題战坤。
# 排除字符
echo 'geek\ngood' | grep '[^o]'
要通過(guò) grep 使用擴(kuò)展正則表達(dá)式需要加上 -E 參數(shù)曙强,或使用 egrep。
# 只匹配"zo"
echo 'zero\nzo\nzoo' | grep -E 'zo{1}'
# 匹配以"zo"開頭的所有單詞
echo 'zero\nzo\nzoo' | grep -E 'zo{1,}'
# 匹配"www.shiyanlou.com"和"www.google.com"
echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -E 'www\.(shiyanlou|google)\.com'
# 或者匹配不包含"baidu"的內(nèi)容
echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -Ev 'www\.baidu\.com'
sed
用于過(guò)濾和轉(zhuǎn)換文本的流編輯器途茫。
sed 命令基本格式:
sed [參數(shù)]... [執(zhí)行命令] [輸入文件]...
# 形如:
$ sed -i 's/sad/happy/' test # 表示將test文件中的"sad"替換為"happy"
sed 執(zhí)行命令格式:
[n1][,n2]command
[n1][~step]command
其中一些命令可以在后面加上作用范圍碟嘴,形如:
sed -i 's/sad/happy/g' test # g 表示全局范圍
sed -i 's/sad/happy/4' test # 4 表示指定行中的第四個(gè)匹配字符串
其中 n1,n2 表示輸入內(nèi)容的行號(hào),它們之間為 , 逗號(hào)則表示從 n1 到 n2 行囊卜,如果為 ~ 波浪號(hào)則表示從 n1 開始以 step 為步進(jìn)的所有行娜扇;command 為執(zhí)行動(dòng)作,下面為一些常用動(dòng)作指令:
cp /etc/passwd ~
# 打印2-5行
nl passwd | sed -n '2,5p'
# 打印奇數(shù)行
nl passwd | sed -n '1~2p'
行內(nèi)替換
# 將輸入文本中"shiyanlou" 全局替換為"hehe"栅组,并只打印替換的那一行雀瓢,注意這里不能省略最后的"p"命令
sed -n 's/shiyanlou/hehe/gp' passwd
刪除某行
nl passwd | grep "shiyanlou"
# 刪除第30行
sed -i '30d' passwd
awk
AWK 是一種用于處理文本的編程語(yǔ)言工具。
whereis awk
ll /usr/bin/awk
ll /usr/bin/mawk
awk 所有的操作都是基于 pattern(模式)—action(動(dòng)作)對(duì)來(lái)完成的玉掸,如下面的形式:
pattern {action}
其中 pattern 通常是表示用于匹配輸入的文本的“關(guān)系式”或“正則表達(dá)式”刃麸,action 則是表示匹配后將執(zhí)行的動(dòng)作。awk 處理文本的方式司浪,是將文本分割成一些“字段”泊业,然后再對(duì)這些字段進(jìn)行處理,默認(rèn)情況下啊易,awk 以空格作為一個(gè)字段的分割符吁伺,不過(guò)這不是固定的,你可以任意指定分隔符认罩。
awk 命令基本格式
awk [-F fs] [-v var=value] [-f prog-file | 'program text'] [file...]
其中 -F 參數(shù)用于預(yù)先指定前面提到的字段分隔符(還有其他指定字段的方式)箱蝠,-v 用于預(yù)先為 awk 程序指定變量,-f 參數(shù)用于指定 awk 命令要執(zhí)行的程序文件垦垂,或者在不加 -f 參數(shù)的情況下直接將程序語(yǔ)句放在這里宦搬,最后為 awk 需要處理的文本輸入,且可以同時(shí)輸入多個(gè)文本文件劫拗。
vim test
I like linux
www.shiyanlou.com
awk '{
> print
> }' test
在這個(gè)操作中我是省略了 pattern间校,所以 awk 會(huì)默認(rèn)匹配輸入文本的全部?jī)?nèi)容,然后在 {} 花括號(hào)中執(zhí)行動(dòng)作页慷,即 print 打印所有匹配項(xiàng)憔足,這里是全部文本內(nèi)容。
將 test 的第一行的每個(gè)字段單獨(dú)顯示為一行:
awk '{
> if(NR==1){
> print $1 "\n" $2 "\n" $3
> } else {
> print}
> }' test
# 或者
awk '{
> if(NR==1){
> OFS="\n"
> print $1, $2, $3
> } else {
> print}
> }' test
NR 與 OFS酒繁,這兩個(gè)是 awk 內(nèi)建的變量滓彰,NR 表示當(dāng)前讀入的記錄數(shù),你可以簡(jiǎn)單的理解為當(dāng)前處理的行數(shù)州袒,OFS 表示輸出時(shí)的字段分隔符揭绑,默認(rèn)為" "空格,如上圖所見,我們將字段分隔符設(shè)置為 \n 換行符他匪,所以第一行原本以空格為字段分隔的內(nèi)容就分別輸出到單獨(dú)一行了菇存。然后是 $N 其中 N 為相應(yīng)的字段號(hào),這也是 awk 的內(nèi)建變量邦蜜,它表示引用相應(yīng)的字段依鸥,因?yàn)槲覀冞@里第一行只有三個(gè)字段,所以只引用到了 $3悼沈。除此之外另一個(gè)這里沒有出現(xiàn)的$0贱迟,它表示引用當(dāng)前記錄(當(dāng)前行)的全部?jī)?nèi)容。
將 test 的第二行的以點(diǎn)為分段的字段換成以空格為分隔:
awk -F'.' '{
> if(NR==2){
> print $1 "\t" $2 "\t" $3
> }}' test
# 或者
awk '
> BEGIN{
> FS="."
> OFS="\t" # 如果寫為一行絮供,兩個(gè)動(dòng)作語(yǔ)句之間應(yīng)該以";"號(hào)分開
> }{
> if(NR==2){
> print $1, $2, $3
> }}' test
-F 參數(shù)关筒,它是用來(lái)預(yù)先指定待處理記錄的字段分隔符”保可以在 print 語(yǔ)句中直接打印特殊符號(hào)如這里的 \t,print 打印的非變量?jī)?nèi)容都需要用""一對(duì)引號(hào)包圍起來(lái)睡榆。
實(shí)現(xiàn)預(yù)先指定變量分隔符的另一種方式萍肆,即使用 BEGIN,就這個(gè)表達(dá)式指示了胀屿,其后的動(dòng)作將在所有動(dòng)作之前執(zhí)行塘揣,這里是 FS 賦值了新的 . 點(diǎn)號(hào)代替默認(rèn)的空格。
awk 常用的內(nèi)置變量
數(shù)據(jù)提取
在文件 /home/shiyanlou/data2 中匹配數(shù)字開頭的行宿崭,將所有以數(shù)字開頭的行都寫入 /home/shiyanlou/num 文件亲铡。
在文件 /home/shiyanlou/data2 中匹配出正確格式的郵箱,將所有的郵箱寫入 /home/shiyanlou/mail 文件葡兑,注意該文件中每行為一個(gè)郵箱奖蔓。
wget https://labfile.oss.aliyuncs.com/courses/1/data2
grep '^[0-9]' /home/shiyanlou/data2 > /home/shiyanlou/num
grep -E '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$' /home/shiyanlou/data2 >/home/shiyanlou/mail
Linux下軟件安裝
apt
w3m(w3m 是一個(gè)命令行的簡(jiǎn)易網(wǎng)頁(yè)瀏覽器),那么輸入如下命令:
sudo apt-get install w3m
w3m https://www.lanqiao.cn/faq
如果你在安裝一個(gè)軟件之后讹堤,無(wú)法立即使用 Tab 鍵補(bǔ)全這個(gè)命令吆鹤,你可以嘗試先執(zhí)行 source ~/.shrc,然后你就可以使用補(bǔ)全操作洲守。
APT 是 Advance Packaging Tool(高級(jí)包裝工具)的縮寫疑务,是 Debian 及其派生發(fā)行版的軟件包管理器,APT 可以自動(dòng)下載梗醇,配置知允,安裝二進(jìn)制或者源代碼格式的軟件包,因此簡(jiǎn)化了 Unix 系統(tǒng)上管理軟件的過(guò)程叙谨。
我們需要定期從服務(wù)器上下載一個(gè)軟件包列表温鸽,使用 sudo apt-get update 命令來(lái)保持本地的軟件包列表是最新的(有時(shí)你也需要手動(dòng)執(zhí)行這個(gè)操作,比如更換了軟件源)唉俗,而這個(gè)表里會(huì)有軟件依賴信息的記錄嗤朴。
我們安裝 w3m 軟件的時(shí)候配椭,而這個(gè)軟件需要 libgc1c2 這個(gè)軟件包才能正常工作,這個(gè)時(shí)候 apt-get 在安裝軟件的時(shí)候會(huì)一并替我們安裝了雹姊,以保證 w3m 能正常的工作股缸。
apt-get 是用于處理 apt包的公用程序集,我們可以用它來(lái)在線安裝吱雏、卸載和升級(jí)軟件包等
apt-get常用的參數(shù):
很多時(shí)候我們需要重新安裝一個(gè)軟件包敦姻,比如你的系統(tǒng)被破壞,或者一些錯(cuò)誤的配置導(dǎo)致軟件無(wú)法正常工作歧杏。你可以使用如下方式重新安裝:
sudo apt-get --reinstall install <packagename>
何在不知道軟件包完整名的時(shí)候進(jìn)行安裝镰惦,通常我們是使用 Tab 鍵補(bǔ)全軟件包名,同時(shí)安裝多個(gè)軟件包犬绒,可以使用正則表達(dá)式匹配軟件包名進(jìn)行批量安裝旺入。
軟件升級(jí)
# 更新軟件源
sudo apt-get update
# 升級(jí)沒有依賴問(wèn)題的軟件包
sudo apt-get upgrade
# 升級(jí)并解決依賴關(guān)系
sudo apt-get dist-upgrade
卸載軟件
sudo apt-get remove w3m
# 不保留配置文件的移除
sudo apt-get purge w3m
# 或者
sudo apt-get --purge remove w3m
# 移除不再需要的被依賴的軟件包
sudo apt-get autoremove
軟件搜索
當(dāng)自己剛知道了一個(gè)軟件,想下載使用凯力,需要確認(rèn)軟件倉(cāng)庫(kù)里面有沒有茵瘾,就需要用到搜索功能了
sudo apt-cache search softname1 softname2 softname3……
apt-cache 命令則是針對(duì)本地?cái)?shù)據(jù)進(jìn)行相關(guān)操作的工具,search 顧名思義在本地的數(shù)據(jù)庫(kù)中尋找有關(guān) softname1咐鹤,softname2 相關(guān)軟件的信息拗秘。
sudo apt-cache search w3m
dpkg
dpkg 本身是一個(gè)底層的工具。上層的工具祈惶,像是 APT雕旨,被用于從遠(yuǎn)程獲取軟件包以及處理復(fù)雜的軟件包關(guān)系。
dpkg常用參數(shù)介紹:
使用 dpkg 安裝 deb 軟件包
先使用apt-get加上-d參數(shù)只下載不安裝捧请,下載 emacs 編輯器的 deb 包:
sudo apt-get update
sudo apt-get -d install -y emacs
ls /var/cache/apt/archives/
將第一個(gè)deb拷貝到 /home/shiyanlou 目錄下凡涩,并使用dpkg安裝
cp /var/cache/apt/archives/emacs24_24.5+1-6ubuntu1.1_amd64.deb ~
# 安裝之前參看deb包的信息
sudo dpkg -I emacs24_24.5+1-6ubuntu1.1_amd64.deb
如果主機(jī)目前沒有這些被依賴的軟件包,直接使用 dpkg 安裝可能會(huì)存在一些問(wèn)題疹蛉,因?yàn)閐pkg并不能為你解決依賴關(guān)系突照。
# 使用dpkg安裝
sudo dpkg -i emacs24_24.5+1-6ubuntu1.1_amd64.deb
apt-get,使用它的-f參數(shù)了氧吐,修復(fù)依賴關(guān)系的安裝
sudo apt-get update
sudo apt-get -f install -y
使用dpkg -L查看deb包目錄信息
sudo dpkg -L emacs24
從二進(jìn)制包安裝
二進(jìn)制包的安裝比較簡(jiǎn)單讹蘑,我們需要做的只是將從網(wǎng)絡(luò)上下載的二進(jìn)制包解壓后放到合適的目錄,然后將包含可執(zhí)行的主程序文件的目錄添加進(jìn)PATH環(huán)境變量即可筑舅。
Linux 進(jìn)程概念
程序(procedure):不太精確地說(shuō)座慰,程序就是執(zhí)行一系列有邏輯、有順序結(jié)構(gòu)的指令翠拣,幫我們達(dá)成某個(gè)結(jié)果版仔。就如我們?nèi)ゲ宛^,給服務(wù)員說(shuō)我要牛肉蓋澆飯拾因,她執(zhí)行了做牛肉蓋澆飯這么一個(gè)程序条获,最后我們得到了這么一盤牛肉蓋澆飯沫浆。它需要去執(zhí)行僧叉,不然它就像一本武功秘籍,放在那里等人翻看侍郭。
進(jìn)程(process):進(jìn)程是程序在一個(gè)數(shù)據(jù)集合上的一次執(zhí)行過(guò)程鸠珠,在早期的 UNIX遗淳、Linux 2.4 及更早的版本中变泄,它是系統(tǒng)進(jìn)行資源分配和調(diào)度的獨(dú)立基本單位令哟。同上一個(gè)例子,就如我們?nèi)チ瞬宛^妨蛹,給服務(wù)員說(shuō)我要牛肉蓋澆飯屏富,她執(zhí)行了做牛肉蓋澆飯這么一個(gè)程序,而里面做飯的是一個(gè)進(jìn)程蛙卤,做牛肉湯汁的是一個(gè)進(jìn)程狠半,把牛肉湯汁與飯混合在一起的是一個(gè)進(jìn)程,把飯端上桌的是一個(gè)進(jìn)程颤难。它就像是我們?cè)诳次涔γ丶@么一個(gè)過(guò)程典予,然后一個(gè)篇章一個(gè)篇章地去練。
進(jìn)程就是運(yùn)行中的程序乐严。
程序只是一些列指令的集合,是一個(gè)靜止的實(shí)體衣摩,而進(jìn)程不同昂验,進(jìn)程有以下的特性:
動(dòng)態(tài)性:進(jìn)程的實(shí)質(zhì)是一次程序執(zhí)行的過(guò)程,有創(chuàng)建艾扮、撤銷等狀態(tài)的變化既琴。而程序是一個(gè)靜態(tài)的實(shí)體。
并發(fā)性:進(jìn)程可以做到在一個(gè)時(shí)間段內(nèi)泡嘴,有多個(gè)程序在運(yùn)行中甫恩。程序只是靜態(tài)的實(shí)體,所以不存在并發(fā)性酌予。
獨(dú)立性:進(jìn)程可以獨(dú)立分配資源磺箕,獨(dú)立接受調(diào)度,獨(dú)立地運(yùn)行抛虫。
異步性:進(jìn)程以不可預(yù)知的速度向前推進(jìn)松靡。
結(jié)構(gòu)性:進(jìn)程擁有代碼段、數(shù)據(jù)段建椰、PCB(進(jìn)程控制塊雕欺,進(jìn)程存在的唯一標(biāo)志)。也正是因?yàn)橛薪Y(jié)構(gòu)性,進(jìn)程才可以做到獨(dú)立地運(yùn)行屠列。
并發(fā):在一個(gè)時(shí)間段內(nèi)啦逆,宏觀來(lái)看有多個(gè)程序都在活動(dòng),有條不紊的執(zhí)行(每一瞬間只有一個(gè)在執(zhí)行笛洛,只是在一段時(shí)間有多個(gè)程序都執(zhí)行過(guò))
并行:在每一個(gè)瞬間夏志,都有多個(gè)程序都在同時(shí)執(zhí)行,這個(gè)必須有多個(gè) CPU 才行
引入進(jìn)程是因?yàn)閭鹘y(tǒng)意義上的程序已經(jīng)不足以描述 OS 中各種活動(dòng)之間的動(dòng)態(tài)性撞蜂、并發(fā)性盲镶、獨(dú)立性還有相互制約性。程序就像一個(gè)公司蝌诡,只是一些證書溉贿,文件的堆積(靜態(tài)實(shí)體)。而當(dāng)公司運(yùn)作起來(lái)就有各個(gè)部門的區(qū)分浦旱,財(cái)務(wù)部宇色,技術(shù)部,銷售部等等颁湖,就像各個(gè)進(jìn)程宣蠕,各個(gè)部門之間可以獨(dú)立運(yùn)做,也可以有交互(獨(dú)立性甥捺、并發(fā)性)抢蚀。
而隨著程序的發(fā)展越做越大,又會(huì)繼續(xù)細(xì)分镰禾,從而引入了線程的概念皿曲,當(dāng)代多數(shù)操作系統(tǒng)、Linux 2.6 及更新的版本中吴侦,進(jìn)程本身不是基本運(yùn)行單位屋休,而是線程的容器。就像上述所說(shuō)的备韧,每個(gè)部門又會(huì)細(xì)分為各個(gè)工作小組(線程)劫樟,而工作小組需要的資源需要向上級(jí)(進(jìn)程)申請(qǐng)。
線程(thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位织堂。它被包含在進(jìn)程之中叠艳,是進(jìn)程中的實(shí)際運(yùn)作單位。一條線程指的是進(jìn)程中一個(gè)單一順序的控制流易阳,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程虑绵,每條線程并行執(zhí)行不同的任務(wù)。因?yàn)榫€程中幾乎不包含系統(tǒng)資源闽烙,所以執(zhí)行更快翅睛、更有效率声搁。
簡(jiǎn)而言之,一個(gè)程序至少有一個(gè)進(jìn)程捕发,一個(gè)進(jìn)程至少有一個(gè)線程疏旨。線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高扎酷。另外檐涝,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存法挨,從而極大地提高了程序的運(yùn)行效率谁榜。
進(jìn)程的分類
第一個(gè)角度來(lái)看,我們可以分為用戶進(jìn)程與系統(tǒng)進(jìn)程:
用戶進(jìn)程:通過(guò)執(zhí)行用戶程序凡纳、應(yīng)用程序或稱之為內(nèi)核之外的系統(tǒng)程序而產(chǎn)生的進(jìn)程窃植,此類進(jìn)程可以在用戶的控制下運(yùn)行或關(guān)閉。
系統(tǒng)進(jìn)程:通過(guò)執(zhí)行系統(tǒng)內(nèi)核程序而產(chǎn)生的進(jìn)程荐糜,比如可以執(zhí)行內(nèi)存資源分配和進(jìn)程切換等相對(duì)底層的工作巷怜;而且該進(jìn)程的運(yùn)行不受用戶的干預(yù),即使是 root 用戶也不能干預(yù)系統(tǒng)進(jìn)程的運(yùn)行暴氏。
第二角度來(lái)看延塑,我們可以將進(jìn)程分為交互進(jìn)程、批處理進(jìn)程答渔、守護(hù)進(jìn)程:
交互進(jìn)程:由一個(gè) shell 終端啟動(dòng)的進(jìn)程关带,在執(zhí)行過(guò)程中,需要與用戶進(jìn)行交互操作沼撕,可以運(yùn)行于前臺(tái)宋雏,也可以運(yùn)行在后臺(tái)。
批處理進(jìn)程:該進(jìn)程是一個(gè)進(jìn)程集合端朵,負(fù)責(zé)按順序啟動(dòng)其他的進(jìn)程。
守護(hù)進(jìn)程:守護(hù)進(jìn)程是一直運(yùn)行的一種進(jìn)程燃箭,在 Linux 系統(tǒng)啟動(dòng)時(shí)啟動(dòng)冲呢,在系統(tǒng)關(guān)閉時(shí)終止。它們獨(dú)立于控制終端并且周期性的執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件招狸。例如 httpd 進(jìn)程敬拓,一直處于運(yùn)行狀態(tài),等待用戶的訪問(wèn)裙戏。還有經(jīng)常用的 cron(在 centOS 系列為 crond)進(jìn)程乘凸,這個(gè)進(jìn)程為 crontab 的守護(hù)進(jìn)程,可以周期性的執(zhí)行用戶設(shè)定的某些任務(wù)累榜。
進(jìn)程的衍生
我們啟動(dòng)了終端营勤,就是啟動(dòng)了一個(gè) bash 進(jìn)程灵嫌,我們可以在 bash 中再輸入 bash 則會(huì)再啟動(dòng)一個(gè) bash 的進(jìn)程,此時(shí)第二個(gè) bash 進(jìn)程就是由第一個(gè) bash 進(jìn)程創(chuàng)建出來(lái)的葛作,我們一般稱呼第一個(gè) bash 進(jìn)程是第二 bash 進(jìn)程的父進(jìn)程寿羞,第二 bash 進(jìn)程是第一個(gè) bash 進(jìn)程的子進(jìn)程。
fork() 是一個(gè)系統(tǒng)調(diào)用(system call)赂蠢,它的主要作用就是為當(dāng)前的進(jìn)程創(chuàng)建一個(gè)新的進(jìn)程绪穆,這個(gè)新的進(jìn)程就是它的子進(jìn)程,這個(gè)子進(jìn)程除了父進(jìn)程的返回值和 PID 以外其他的都一模一樣虱岂,如進(jìn)程的執(zhí)行代碼段玖院,內(nèi)存信息,文件描述第岖,寄存器狀態(tài)等等难菌。
exec() 也是系統(tǒng)調(diào)用,作用是切換子進(jìn)程中的執(zhí)行程序也就是替換其從父進(jìn)程復(fù)制過(guò)來(lái)的代碼段與數(shù)據(jù)段绍傲。
子進(jìn)程就是父進(jìn)程通過(guò)系統(tǒng)調(diào)用 fork() 而產(chǎn)生的復(fù)制品扔傅,fork() 就是把父進(jìn)程的 PCB 等進(jìn)程的數(shù)據(jù)結(jié)構(gòu)信息直接復(fù)制過(guò)來(lái),只是修改了 PID烫饼,所以一模一樣猎塞,只有在執(zhí)行 exec() 之后才會(huì)不同。
子進(jìn)程的產(chǎn)生實(shí)現(xiàn)邏輯
pid_t p;
p = fork();
if (p == (pid_t) -1)
/* ERROR */
else if (p == 0)
/* CHILD */
else
/* PARENT */
當(dāng)一個(gè)子進(jìn)程要正常的終止運(yùn)行時(shí)杠纵,或者該進(jìn)程結(jié)束時(shí)它的主函數(shù) main() 會(huì)執(zhí)行 exit(n); 或者 return n荠耽,這里的返回值 n 是一個(gè)信號(hào),系統(tǒng)會(huì)把這個(gè) SIGCHLD 信號(hào)傳給其父進(jìn)程比藻,當(dāng)然若是異常終止也往往是因?yàn)檫@個(gè)信號(hào)铝量。
在將要結(jié)束時(shí)的子進(jìn)程代碼執(zhí)行部分已經(jīng)結(jié)束執(zhí)行了,系統(tǒng)的資源也基本歸還給系統(tǒng)了银亲,但若是其進(jìn)程的進(jìn)程控制塊(PCB)仍駐留在內(nèi)存中慢叨,而它的 PCB 還在,代表這個(gè)進(jìn)程還存在(因?yàn)?PCB 就是進(jìn)程存在的唯一標(biāo)志务蝠,里面有 PID 等消息)拍谐,并沒有消亡,這樣的進(jìn)程稱之為僵尸進(jìn)程(Zombie)馏段。
正常情況下轩拨,父進(jìn)程會(huì)收到兩個(gè)返回值:exit code(SIGCHLD 信號(hào))與 reason for termination 。之后院喜,父進(jìn)程會(huì)使用 wait(&status) 系統(tǒng)調(diào)用以獲取子進(jìn)程的退出狀態(tài)亡蓉,然后內(nèi)核就可以從內(nèi)存中釋放已結(jié)束的子進(jìn)程的 PCB;而如若父進(jìn)程沒有這么做的話喷舀,子進(jìn)程的 PCB 就會(huì)一直駐留在內(nèi)存中砍濒,一直留在系統(tǒng)中成為僵尸進(jìn)程(Zombie)淋肾。
雖然僵尸進(jìn)程是已經(jīng)放棄了幾乎所有內(nèi)存空間,沒有任何可執(zhí)行代碼梯影,也不能被調(diào)度巫员,在進(jìn)程列表中保留一個(gè)位置,記載該進(jìn)程的退出狀態(tài)等信息供其父進(jìn)程收集甲棍,從而釋放它简识。但是 Linux 系統(tǒng)中能使用的 PID 是有限的,如果系統(tǒng)中存在有大量的僵尸進(jìn)程感猛,系統(tǒng)將會(huì)因?yàn)闆]有可用的 PID 從而導(dǎo)致不能產(chǎn)生新的進(jìn)程七扰。
另外如果父進(jìn)程結(jié)束(非正常的結(jié)束),未能及時(shí)收回子進(jìn)程陪白,子進(jìn)程仍在運(yùn)行颈走,這樣的子進(jìn)程稱之為孤兒進(jìn)程。在 Linux 系統(tǒng)中咱士,孤兒進(jìn)程一般會(huì)被 init 進(jìn)程所“收養(yǎng)”立由,成為 init 的子進(jìn)程。由 init 來(lái)做善后處理序厉,所以它并不至于像僵尸進(jìn)程那樣無(wú)人問(wèn)津锐膜,不管不顧,大量存在會(huì)有危害弛房。
進(jìn)程 0 是系統(tǒng)引導(dǎo)時(shí)創(chuàng)建的一個(gè)特殊進(jìn)程道盏,也稱之為內(nèi)核初始化,其最后一個(gè)動(dòng)作就是調(diào)用 fork() 創(chuàng)建出一個(gè)子進(jìn)程運(yùn)行 /sbin/init 可執(zhí)行文件文捶,而該進(jìn)程就是 PID=1 的進(jìn)程 1荷逞,而進(jìn)程 0 就轉(zhuǎn)為交換進(jìn)程(也被稱為空閑進(jìn)程),進(jìn)程 1 (init 進(jìn)程)是第一個(gè)用戶態(tài)的進(jìn)程粹排,再由它不斷調(diào)用 fork() 來(lái)創(chuàng)建系統(tǒng)里其他的進(jìn)程种远,所以它是所有進(jìn)程的父進(jìn)程或者祖先進(jìn)程。同時(shí)它是一個(gè)守護(hù)程序顽耳,直到計(jì)算機(jī)關(guān)機(jī)才會(huì)停止坠敷。
進(jìn)程關(guān)系
pstree
ps -fxo user,ppid,pid,pgid,command
其中 pid 就是該進(jìn)程的一個(gè)唯一編號(hào),ppid 就是該進(jìn)程的父進(jìn)程的 pid斧抱,command 表示的是該進(jìn)程通過(guò)執(zhí)行什么樣的命令或者腳本而產(chǎn)生的
進(jìn)程組與 Sessions
每一個(gè)進(jìn)程都會(huì)是一個(gè)進(jìn)程組的成員常拓,而且這個(gè)進(jìn)程組是唯一存在的渐溶,他們是依靠 PGID(process group ID)來(lái)區(qū)別的辉浦,而每當(dāng)一個(gè)進(jìn)程被創(chuàng)建的時(shí)候,它便會(huì)成為其父進(jìn)程所在組中的一員茎辐。
一般情況宪郊,進(jìn)程組的 PGID 等同于進(jìn)程組的第一個(gè)成員的 PID掂恕,并且這樣的進(jìn)程稱為該進(jìn)程組的領(lǐng)導(dǎo)者,也就是領(lǐng)導(dǎo)進(jìn)程弛槐,進(jìn)程一般通過(guò)使用 getpgrp() 系統(tǒng)調(diào)用來(lái)尋找其所在組的 PGID懊亡,領(lǐng)導(dǎo)進(jìn)程可以先終結(jié),此時(shí)進(jìn)程組依然存在乎串,并持有相同的 PGID店枣,直到進(jìn)程組中最后一個(gè)進(jìn)程終結(jié)。
與進(jìn)程組類似叹誉,每當(dāng)一個(gè)進(jìn)程被創(chuàng)建的時(shí)候鸯两,它便會(huì)成為其父進(jìn)程所在 Session 中的一員,每一個(gè)進(jìn)程組都會(huì)在一個(gè) Session 中长豁,并且這個(gè) Session 是唯一存在的钧唐,Session 主要是針對(duì)一個(gè) tty 建立,Session 中的每個(gè)進(jìn)程都稱為一個(gè)工作(job)匠襟。每個(gè)會(huì)話可以連接一個(gè)終端(control terminal)钝侠。當(dāng)控制終端有輸入輸出時(shí),都傳遞給該會(huì)話的前臺(tái)進(jìn)程組酸舍。Session 意義在于將多個(gè) jobs 囊括在一個(gè)終端帅韧,并取其中的一個(gè) job 作為前臺(tái),來(lái)直接接收該終端的輸入輸出以及終端信號(hào)父腕。 其他 jobs 在后臺(tái)運(yùn)行弱匪。
前臺(tái)(foreground)就是在終端中運(yùn)行,能與你有交互的
后臺(tái)(background)就是在終端中運(yùn)行璧亮,但是你并不能與其任何的交互萧诫,也不會(huì)顯示其執(zhí)行的過(guò)程
工作管理
bash(Bourne-Again shell)支持工作控制(job control),而 sh(Bourne shell)并不支持枝嘶。
并且每個(gè)終端或者說(shuō) bash 只能管理當(dāng)前終端中的 job帘饶,不能管理其他終端中的 job。比如我當(dāng)前存在兩個(gè) bash 分別為 bash1群扶、bash2及刻,bash1 只能管理其自己里面的 job 并不能管理 bash2 里面的 job
我們可以通過(guò) & 這個(gè)符號(hào),讓我們的命令在后臺(tái)中運(yùn)行:我們還可以通過(guò) ctrl + z 使我們的當(dāng)前工作停止并丟到后臺(tái)中去
被停止并放置在后臺(tái)的工作我們可以使用這個(gè)命令來(lái)查看:
jobs
其中第一列顯示的為被放置后臺(tái) job 的編號(hào)竞阐,而第二列的 + 表示最近(剛剛缴饭、最后)被放置后臺(tái)的 job,同時(shí)也表示預(yù)設(shè)的工作骆莹,也就是若是有什么針對(duì)后臺(tái) job 的操作颗搂,首先對(duì)預(yù)設(shè)的 job,- 表示倒數(shù)第二(也就是在預(yù)設(shè)之前的一個(gè))被放置后臺(tái)的工作幕垦,倒數(shù)第三個(gè)(再之前的)以后都不會(huì)有這樣的符號(hào)修飾丢氢,第三列表示它們的狀態(tài)傅联,而最后一列表示該進(jìn)程執(zhí)行的命令。
我們可以通過(guò)這樣的一個(gè)命令將后臺(tái)的工作拿到前臺(tái)來(lái):
# 后面不加參數(shù)提取預(yù)設(shè)工作疚察,加參數(shù)提取指定工作的編號(hào)
# ubuntu 在 zsh 中需要 %蒸走,在 bash 中不需要 %
fg [%jobnumber]
若是我們想讓其在后臺(tái)運(yùn)作我們就使用這樣一個(gè)命令:
#與fg類似,加參則指定貌嫡,不加參則取預(yù)設(shè)
bg [%jobnumber]
# kill的使用格式如下
kill -signal %jobnumber
# signal從1-64個(gè)信號(hào)值可以選擇比驻,可以這樣查看
kill -l
若是在使用 kill +信號(hào)值然后直接加 pid,你將會(huì)對(duì) pid 對(duì)應(yīng)的進(jìn)程進(jìn)行操作岛抄。
若是在使用 kill+信號(hào)值然后 %jobnumber嫁艇,這時(shí)所操作的對(duì)象是 job,這個(gè)數(shù)字就是就當(dāng)前 bash 中后臺(tái)的運(yùn)行的 job 的 ID弦撩。
Linux 進(jìn)程管理
top 工具的使用
top 是一個(gè)在前臺(tái)執(zhí)行的程序步咪,正是因?yàn)榻换ソ缑嫖覀儾趴梢詫?shí)時(shí)的獲取到系統(tǒng)與進(jìn)程的信息。在交互界面中我們可以通過(guò)一些指令來(lái)操作和篩選益楼。
我們看到 top 顯示的第一排:
load average是指運(yùn)行隊(duì)列的平均長(zhǎng)度猾漫,也就是等待 CPU 的平均進(jìn)程數(shù)相關(guān)的一個(gè)計(jì)算值。
假設(shè)我們的系統(tǒng)是單 CPU感凤、單內(nèi)核的悯周,把它比喻成是一條單向的橋,把 CPU 任務(wù)比作汽車陪竿。
load = 0 的時(shí)候意味著這個(gè)橋上并沒有車禽翼,cpu 沒有任何任務(wù);
load < 1 的時(shí)候意味著橋上的車并不多族跛,一切都還是很流暢的闰挡,cpu 的任務(wù)并不多,資源還很充足;
load = 1 的時(shí)候就意味著橋已經(jīng)被車給占滿了,沒有一點(diǎn)空隙纽谒,cpu 已經(jīng)在全力工作了,所有的資源都被用完了夺脾,當(dāng)然還好,這還在能力范圍之內(nèi)茉继,只是有點(diǎn)慢而已咧叭;
load > 1 的時(shí)候就意味著不僅僅是橋上已經(jīng)被車占滿了,就連橋外都被占滿了烁竭,cpu 已經(jīng)在全力工作菲茬,系統(tǒng)資源的用完了,但是還是有大量的進(jìn)程在請(qǐng)求,在等待生均。若是這個(gè)值大于 2 表示進(jìn)程請(qǐng)求超過(guò) CPU 工作能力的 2 倍。而若是這個(gè)值大于 5 說(shuō)明系統(tǒng)已經(jīng)在超負(fù)荷運(yùn)作了腥刹。
#查看物理 CPU 的個(gè)數(shù)
cat /proc/cpuinfo | grep "physical id" | sort | uniq |wc -l
#每個(gè) cpu 的核心數(shù)
cat /proc/cpuinfo | grep "physical id" | grep "0" | wc -l
在實(shí)際生活中马胧,比較有經(jīng)驗(yàn)的運(yùn)維或者系統(tǒng)管理員會(huì)將臨界值定為 0.7,這里的指數(shù)都是除以核心數(shù)以后的值。
若是 load < 0.7 并不會(huì)去關(guān)注他衔峰;
若是 0.7< load < 1 的時(shí)候我們就需要稍微關(guān)注一下了佩脊,雖然還可以應(yīng)付但是這個(gè)值已經(jīng)離臨界不遠(yuǎn)了;
若是 load = 1 的時(shí)候我們就需要警惕了垫卤,因?yàn)檫@個(gè)時(shí)候已經(jīng)沒有更多的資源的了威彰,已經(jīng)在全力以赴了;
若是 load > 5 的時(shí)候系統(tǒng)已經(jīng)快不行了穴肘,這個(gè)時(shí)候你需要加班解決問(wèn)題了
通常我們都會(huì)先看 15 分鐘的值來(lái)看這個(gè)大體的趨勢(shì)歇盼,然后再看 5 分鐘的值對(duì)比來(lái)看是否有下降的趨勢(shì)。
查看 busybox 的代碼可以知道评抚,數(shù)據(jù)是每 5 秒鐘就檢查一次活躍的進(jìn)程數(shù)豹缀,然后計(jì)算出該值,然后 load 從 /proc/loadavg 中讀取的慨代。
top 的第二行數(shù)據(jù)邢笙,基本上第二行是進(jìn)程的一個(gè)情況統(tǒng)計(jì):
top 的第三行數(shù)據(jù),這一行基本上是 CPU 的一個(gè)使用情況的統(tǒng)計(jì)了:
CPU 利用率是對(duì)一個(gè)時(shí)間段內(nèi) CPU 使用狀況的統(tǒng)計(jì)侍匙,通過(guò)這個(gè)指標(biāo)可以看出在某一個(gè)時(shí)間段內(nèi) CPU 被占用的情況氮惯,而 Load Average 是 CPU 的 Load,它所包含的信息不是 CPU 的使用率狀況想暗,而是在一段時(shí)間內(nèi) CPU 正在處理以及等待 CPU 處理的進(jìn)程數(shù)情況統(tǒng)計(jì)信息妇汗,這兩個(gè)指標(biāo)并不一樣。
top 的第四行數(shù)據(jù)说莫,這一行基本上是內(nèi)存的一個(gè)使用情況的統(tǒng)計(jì)了:
系統(tǒng)中可用的物理內(nèi)存最大值并不是 free 這個(gè)單一的值铛纬,而是 free + buffers + swap 中的 cached 的和。
top 的第五行數(shù)據(jù)唬滑,這一行基本上是交換區(qū)的一個(gè)使用情況的統(tǒng)計(jì)了:
NICE 值叫做靜態(tài)優(yōu)先級(jí)告唆,是用戶空間的一個(gè)優(yōu)先級(jí)值,其取值范圍是 -20 至 19晶密。這個(gè)值越小擒悬,表示進(jìn)程”優(yōu)先級(jí)”越高,而值越大“優(yōu)先級(jí)”越低稻艰。nice 值中的 -20 到 19懂牧,中 -20 優(yōu)先級(jí)最高, 0 是默認(rèn)的值,而 19 優(yōu)先級(jí)最低僧凤。
PR 值表示 Priority 值叫動(dòng)態(tài)優(yōu)先級(jí)畜侦,是進(jìn)程在內(nèi)核中實(shí)際的優(yōu)先級(jí)值,進(jìn)程優(yōu)先級(jí)的取值范圍是通過(guò)一個(gè)宏定義的躯保,這個(gè)宏的名稱是 MAX_PRIO旋膳,它的值為 140。Linux 實(shí)際上實(shí)現(xiàn)了 140 個(gè)優(yōu)先級(jí)范圍途事,取值范圍是從 0-139验懊,這個(gè)值越小,優(yōu)先級(jí)越高尸变。而這其中的 0-99 是實(shí)時(shí)進(jìn)程的值义图,而 100-139 是給用戶的。
其中 PR 中的 100 to 139 值部分有這么一個(gè)對(duì)應(yīng) PR = 20 + (-20 to +19)召烂,這里的 -20 to +19 便是 nice 值碱工,所以說(shuō)兩個(gè)雖然都是優(yōu)先級(jí),而且有千絲萬(wàn)縷的關(guān)系奏夫,但是他們的值痛垛,他們的作用范圍并不相同。
VIRT 任務(wù)所使用的虛擬內(nèi)存的總數(shù)桶蛔,其中包含所有的代碼匙头,數(shù)據(jù),共享庫(kù)和被換出 swap 空間的頁(yè)面等所占據(jù)空間的總數(shù)仔雷。
ps 工具的使用
ps 是我們最常用的查看進(jìn)程的工具之一
TPGID欄寫著-1 的都是沒有控制終端的進(jìn)程蹂析,也就是守護(hù)進(jìn)程
STAT表示進(jìn)程的狀態(tài),而進(jìn)程的狀態(tài)有很多碟婆,如下表所示:
其中的 D 是不能被中斷睡眠的狀態(tài)电抚,處在這種狀態(tài)的進(jìn)程不接受外來(lái)的任何 signal,所以無(wú)法使用 kill 命令殺掉處于 D 狀態(tài)的進(jìn)程竖共,無(wú)論是 kill蝙叛,kill -9 還是 kill -15,一般處于這種狀態(tài)可能是進(jìn)程 I/O 的時(shí)候出問(wèn)題了公给。
使用 -l 參數(shù)可以顯示自己這次登錄的 bash 相關(guān)的進(jìn)程信息羅列出來(lái):
ps -l
羅列出所有的進(jìn)程信息:
ps aux
若是查找其中的某個(gè)進(jìn)程的話借帘,我們還可以配合著 grep 和正則表達(dá)式一起使用
ps aux | grep zsh
可以查看時(shí),將連同部分的進(jìn)程呈樹狀顯示出來(lái):
ps axjf
自定義我們所需要的參數(shù)顯示:
ps -afxo user,ppid,pid,pgid,command
pstree 工具的使用
通過(guò) pstree 可以很直接的看到相同的進(jìn)程數(shù)量淌铐,最主要的還是我們可以看到所有進(jìn)程之間的相關(guān)性肺然。
pstree
pstree -up
kill 命令
我們可以使用 kill 來(lái)發(fā)送這個(gè)信號(hào)來(lái)操作進(jìn)程的結(jié)束或者重啟等等
# 首先我們使用圖形界面打開了 gedit、gvim腿准,用 ps 可以查看到
ps aux
# 使用 9 這個(gè)信號(hào)強(qiáng)制結(jié)束 gedit 進(jìn)程
kill -9 1608
# 我們?cè)俨檎疫@個(gè)進(jìn)程的時(shí)候就找不到了
ps aux | grep gedit
進(jìn)程的執(zhí)行順序
nice 的值我們是可以通過(guò) nice 命令來(lái)修改的际起,而需要注意的是 nice 值可以調(diào)整的范圍是 -20 ~ 19,其中 root 有著至高無(wú)上的權(quán)力,既可以調(diào)整自己的進(jìn)程也可以調(diào)整其他用戶的程序街望,并且是所有的值都可以用校翔,而普通用戶只可以調(diào)制屬于自己的進(jìn)程,并且其使用的范圍只能是 0 ~ 19灾前,因?yàn)橄到y(tǒng)為了避免一般用戶搶占系統(tǒng)資源而設(shè)置的一個(gè)限制
# 打開一個(gè)程序放在后臺(tái)防症,或者用圖形界面打開
nice -n -5 vim &
# 用 ps 查看其優(yōu)先級(jí)
ps -afxo user,ppid,pid,stat,pri,ni,time,command | grep vim
可以用 renice 來(lái)修改已經(jīng)存在的進(jìn)程的優(yōu)先級(jí)
renice -5 pid
Linux 日志系統(tǒng)
日志它可以記錄下系統(tǒng)產(chǎn)生的所有行為,并按照某種規(guī)范表達(dá)出來(lái)豫柬。我們可以使用日志系統(tǒng)所記錄的信息為系統(tǒng)進(jìn)行排錯(cuò),優(yōu)化系統(tǒng)的性能扑浸,或者根據(jù)這些信息調(diào)整系統(tǒng)的行為烧给。收集你想要的數(shù)據(jù),分析出有價(jià)值的信息喝噪,可以提高系統(tǒng)础嫡、產(chǎn)品的安全性,還可以幫助開發(fā)完善代碼酝惧,優(yōu)化產(chǎn)品榴鼎。
常見的日志
日志是一個(gè)系統(tǒng)管理員,一個(gè)運(yùn)維人員晚唇,甚至是開發(fā)人員不可或缺的東西巫财,系統(tǒng)用久了偶爾也會(huì)出現(xiàn)一些錯(cuò)誤,我們需要日志來(lái)給系統(tǒng)排錯(cuò)哩陕,在一些網(wǎng)絡(luò)應(yīng)用服務(wù)不能正常工作的時(shí)候平项,我們需要用日志來(lái)做問(wèn)題定位,日志還是過(guò)往時(shí)間的記錄本悍及,我們可以通過(guò)它知道我們是否被不明用戶登錄過(guò)等等闽瓢。
ll /var/log
系統(tǒng)日志主要是存放系統(tǒng)內(nèi)置程序或系統(tǒng)內(nèi)核之類的日志信息如 alternatives.log 、btmp 等等心赶,應(yīng)用日志主要是我們裝的第三方應(yīng)用所產(chǎn)生的日志如 tomcat7 扣讼、apache2 等等。
查看auth.log 中的信息:
sudo less /var/log/auth.log
在 /var/log/apt 文件夾中有兩個(gè)日志文件 history.log 與 term.log缨叫,兩個(gè)日志文件的區(qū)別在于 history.log 主要記錄了進(jìn)行了哪個(gè)操作椭符,相關(guān)的依賴有哪些,而 term.log 則是較為具體的一些操作耻姥,主要就是下載包艰山,打開包,安裝包等等的細(xì)節(jié)操作咏闪。
如果是剛剛開啟的新系統(tǒng)曙搬,那么按理說(shuō)這些日志應(yīng)該都是空的
sudo cat /var/log/apt/history.log
sudo cat /var/log/apt/term.log
其他的日志格式主要便是時(shí)間,操作。而這其中有兩個(gè)比較特殊的日志纵装,其查看的方式比較與眾不同征讲,因?yàn)檫@兩個(gè)日志并不是 ASCII 文件而是被編碼成了二進(jìn)制文件,所以我們并不能直接使用 less橡娄、cat诗箍、more 這樣的工具來(lái)查看,這兩個(gè)日志文件是 wtmp挽唉,lastlog
配置的日志
一種是由軟件開發(fā)商自己來(lái)自定義日志格式然后指定輸出日志位置滤祖;
一種方式就是 Linux 提供的日志服務(wù)程序,而我們這里系統(tǒng)日志是通過(guò) syslog 來(lái)實(shí)現(xiàn)瓶籽,提供日志管理服務(wù)匠童。
syslog 是一個(gè)系統(tǒng)日志記錄程序,在早期的大部分 Linux 發(fā)行版都是內(nèi)置 syslog塑顺,讓其作為系統(tǒng)的默認(rèn)日志收集工具汤求,雖然隨著時(shí)代的進(jìn)步與發(fā)展,syslog 已經(jīng)年老體衰跟不上時(shí)代的需求严拒,所以他被 rsyslog 所代替了扬绪,較新的 Ubuntu、Fedora 等等都是默認(rèn)使用 rsyslog 作為系統(tǒng)的日志收集工具
rsyslog 的全稱是 rocket-fast system for log裤唠,它提供了高性能挤牛,高安全功能和模塊化設(shè)計(jì)。rsyslog 能夠接受各種各樣的來(lái)源种蘸,將其輸入赊颠,輸出的結(jié)果到不同的目的地。rsyslog 可以提供超過(guò)每秒一百萬(wàn)條消息給目標(biāo)文件劈彪。
這樣能實(shí)時(shí)收集日志信息的程序是有其守護(hù)進(jìn)程的竣蹦,如 rsyslog 的守護(hù)進(jìn)程便是 rsyslogd
sudo apt-get update
sudo apt-get install -y rsyslog
sudo service rsyslog start
ps aux | grep syslog
rsyslog 的配置文件有兩個(gè),
一個(gè)是 /etc/rsyslog.conf
一個(gè)是 /etc/rsyslog.d/50-default.conf沧奴。
第一個(gè)主要是配置的環(huán)境痘括,也就是 rsyslog 加載什么模塊,文件的所屬者等滔吠;而第二個(gè)主要是配置的 Filter Conditions
vim /etc/rsyslog.conf
vim /etc/rsyslog.d/50-default.conf
通過(guò)這個(gè)簡(jiǎn)單的流程圖我們可以知道 rsyslog 主要是由 Input纲菌、Output、Parser 這樣三個(gè)模塊構(gòu)成的疮绷,并且了解到數(shù)據(jù)的簡(jiǎn)單走向翰舌,首先通過(guò) Input module 來(lái)收集消息,然后將得到的消息傳給 Parser module冬骚,通過(guò)分析模塊的層層處理椅贱,將真正需要的消息傳給 Output module懂算,然后便輸出至日志文件中。
rsyslog 號(hào)稱可以提供超過(guò)每秒一百萬(wàn)條消息給目標(biāo)文件
Rsyslog 架構(gòu)如圖中所示庇麦,從圖中我們可以很清楚的看見计技,rsyslog 還有一個(gè)核心的功能模塊便是 Queue,也正是因?yàn)樗拍茏龅饺绱烁叩牟l(fā)山橄。
第一個(gè)模塊便是 Input垮媒,該模塊的主要功能就是從各種各樣的來(lái)源收集 messages,通過(guò)這些接口實(shí)現(xiàn):
這些模塊接口的使用需要通過(guò) )開頭的語(yǔ)法驳阎,在 v6 及以上的版本還在支持抗愁,就如上文所說(shuō)的 開頭的指令是全局指令呵晚,全局指令是 rsyslogd 守護(hù)進(jìn)程的配置指令,每行只能有一個(gè)指令沫屡。 RainnerScript 是最新的語(yǔ)法饵隙。在官網(wǎng)上 rsyslog 大多推薦這個(gè)語(yǔ)法格式來(lái)配置
老的語(yǔ)法格式(sysklogd & legacy rsyslog)是以行為單位。新的語(yǔ)法格式(RainnerScript)可以分割多行沮脖。
注釋有兩種語(yǔ)法:
井號(hào) #
C-style /* .. */
執(zhí)行順序: 指令在 rsyslog.conf 文件中是從上到下的順序執(zhí)行的金矛。
模板是 rsyslog 一個(gè)重要的屬性,它可以控制日志的格式勺届,支持類似 template() 語(yǔ)句的基于 string 或 plugin 的模板驶俊,通過(guò)它我們可以自定義日志格式。
legacy 格式使用 $template 的語(yǔ)法免姿,不過(guò)這個(gè)在以后要移除饼酿,所以最好使用新格式 template():,以免未來(lái)突然不工作了也不知道為什么
模板定義的形式有四種胚膊,適用于不同的輸出模塊故俐,一般簡(jiǎn)單的格式,可以使用 string 的形式紊婉,復(fù)雜的格式药版,建議使用 list 的形式,使用 list 的形式喻犁,可以使用一些額外的屬性字段(property statement)
如果不指定輸出模板槽片,rsyslog 會(huì)默認(rèn)使用 RSYSLOG_DEFAULT何缓。
/etc/rsyslog.d/50-default.conf 這個(gè)配置文件,這個(gè)文件中主要是配置的 Filter Conditions筐乳,也就是我們?cè)诹鞒虉D中所看見的 Parser & Filter Engine歌殃,它的名字叫 Selectors 是過(guò)濾 syslog 的傳統(tǒng)方法,他主要由兩部分組成蝙云,facility 與 priority氓皱,其配置格式如下:
facility.priority log_location
其中一個(gè) priority 可以指定多個(gè) facility,多個(gè) facility 之間使用逗號(hào) , 分割開
rsyslog 通過(guò) Facility 的概念來(lái)定義日志消息的來(lái)源勃刨,以便對(duì)日志進(jìn)行分類波材,F(xiàn)acility 的種類有:
另外一部分 priority 也稱之為 serverity level,除了日志的來(lái)源以外身隐,對(duì)統(tǒng)一源產(chǎn)生日志消息還需要進(jìn)行優(yōu)先級(jí)的劃分廷区,而優(yōu)先級(jí)的類別有以下幾種:
auth,authpriv.* /var/log/auth.log
這里的意思是 auth 與 authpriv 的所有優(yōu)先級(jí)的信息全都輸出于 /var/log/auth.log 日志中
而其中有類似于這樣的配置信息意思有細(xì)微的差別
kern.* -/var/log/kern.log
- 代表異步寫入,也就是日志寫入時(shí)不需要等待系統(tǒng)緩存的同步贾铝,也就是日志還在內(nèi)存中緩存也可以繼續(xù)寫入無(wú)需等待完全寫入硬盤后再寫入隙轻。通常用于寫入數(shù)據(jù)比較大時(shí)使用。
需要注意的是 rsyslog 每個(gè)版本之間差異化比較大垢揩,學(xué)習(xí)之前先查看自己所使用的版本玖绿,再去查看相關(guān)的文檔
與日志相關(guān)的還有一個(gè)還有常用的命令 logger,logger 是一個(gè) shell 命令接口叁巨,可以通過(guò)該接口使用 Syslog 的系統(tǒng)日志模塊斑匪,還可以從命令行直接向系統(tǒng)日志文件寫入信息。
#首先將syslog啟動(dòng)起來(lái)
sudo service rsyslog start
#向 syslog 寫入數(shù)據(jù)
ping 127.0.0.1 | logger -it logger_test -p local3.notice &
#查看是否有數(shù)據(jù)寫入
sudo tail -f /var/log/syslog
我們可以通過(guò) man 來(lái)查看 logger 的其他用法锋勺,
轉(zhuǎn)儲(chǔ)的日志
logrotate 程序是一個(gè)日志文件管理工具蚀瘸。用來(lái)把舊的日志文件刪除,并創(chuàng)建新的日志文件庶橱。我們可以根據(jù)日志文件的大小贮勃,也可以根據(jù)其天數(shù)來(lái)切割日志、管理日志苏章,這個(gè)過(guò)程又叫做“轉(zhuǎn)儲(chǔ)”寂嘉。
大多數(shù) Linux 發(fā)行版使用 logrotate 或 newsyslog 對(duì)日志進(jìn)行管理。logrotate 程序不但可以壓縮日志文件布近,減少存儲(chǔ)空間垫释,還可以將日志發(fā)送到指定 E-mail,方便管理員及時(shí)查看日志撑瞧。
logrotate 是基于 CRON 來(lái)運(yùn)行的棵譬,其腳本是 /etc/cron.daily/logrotate;同時(shí)我們可以在 /etc/logrotate 中找到其配置文件
cat /etc/logrotate.conf
# see "man logrotate" for details //可以查看幫助文檔
# rotate log files weekly
weekly //設(shè)置每周轉(zhuǎn)儲(chǔ)一次(daily预伺、weekly订咸、monthly當(dāng)然可以使用這些參數(shù)每天曼尊、星期,月 )
# keep 4 weeks worth of backlogs
rotate 4 //最多轉(zhuǎn)儲(chǔ)4次
# create new (empty) log files after rotating old ones
create //當(dāng)轉(zhuǎn)儲(chǔ)后文件不存在時(shí)創(chuàng)建它
# uncomment this if you want your log files compressed
compress //通過(guò)gzip壓縮方式轉(zhuǎn)儲(chǔ)(nocompress可以不壓縮)
# RPM packages drop log rotation information into this directory
include /etc/logrotate.d //其他日志文件的轉(zhuǎn)儲(chǔ)方式配置文件脏嚷,包含在該目錄下
# no packages own wtmp -- we'll rotate them here
/var/log/wtmp { //設(shè)置/var/log/wtmp日志文件的轉(zhuǎn)儲(chǔ)參數(shù)
monthly //每月轉(zhuǎn)儲(chǔ)
create 0664 root utmp //轉(zhuǎn)儲(chǔ)后文件不存在時(shí)創(chuàng)建它骆撇,文件所有者為root,所屬組為utmp父叙,對(duì)應(yīng)的權(quán)限為0664
rotate 1 //最多轉(zhuǎn)儲(chǔ)一次
}