有很多同學微信問我,Linux指令這麼多,該怎麼從入門到精通?其實,這個事情非常的simple,這篇文章将會帶你飛。文章非常的長,要挑一個陽光明媚的sunshine weekend,耐心去搞定。
看完此篇文章,你會對Linux指令有客觀的了解,你在使用Freemen APP找工作的時候會有更大的競争力,Freemen APP,程式員自己的求職平台,歡迎大家下載下傳為自己升值加薪增加一個管道。
本文将由一個Linux指令概覽開始,說明Linux指令的方方面面。如果你讀完這部分還是一頭霧水,那麼就證明需要按照下面的小白教程去學習了,内容涵蓋了:如何挑選Linux發行版、如何安裝Linux系統,按照主題學習Linux系統的指令等。
入門後的 **學習方式:多敲多打,用條件反射替代大腦記憶--如果你将來或者現在要用它來吃飯的話。**其中,也有一些難啃的骨頭,關注小姐姐味道微信公衆号,我們一起用鋒利的牙齒,來把它嚼碎。
1. Linux指令概覽
這部分是給稍微有點Linux經驗的同學準備的,如果你是初學者,請跳過此part直接進入第二部分。
1.1目錄操作
工作中,最常打交道的就是對目錄和檔案的操作。linux提供了相應的指令去操作他,并将這些指令抽象、縮寫。
1.1.1 基本操作
可能是這些指令太常用了,多打一個字元都是罪過。是以它們都很短,不用阿拉伯數字,一個剪刀手就能數過來。
看指令。
mkdir 建立目錄 make dircp 拷貝檔案 copymv 移動檔案 moverm 删除檔案 remove
例子:
# 建立目錄和父目錄a,b,c,d
mkdir -p a/b/c/d
# 拷貝檔案夾a到/tmp目錄
cp -rvf a/ /tmp/
# 移動檔案a到/tmp目錄,并重命名為b
mv -vf a /tmp/b
# 删除機器上的所有檔案
rm -rvf /
1.1.2 漫遊
linux上是黑漆漆的指令行,依然要面臨人生三問:我是誰?我在哪?我要去何方?
ls 指令能夠看到目前目錄的所有内容。ls -l能夠看到更多資訊,判斷你是誰。
pwd 指令能夠看到目前終端所在的目錄。告訴你你在哪。
cd 假如你去錯了地方,cd指令能夠切換到對的目錄。
find find指令通過篩選一些條件,能夠找到已經被遺忘的檔案。
至于要去何方,可能就是主宰者的意志了。
1.2 文本處理
這是是非常非常加分的技能。get到之後,也能節省更多時間來研究面向對象。小姐姐味道已經輸出了“最常用的vim、sed、awk技巧系列”。
1.2.1 檢視檔案
cat
最常用的就是cat指令了,注意,如果檔案很大的話,cat指令的輸出結果會瘋狂在終端上輸出,可以多次按ctrl+c終止。
# 檢視檔案大小
du -h file
# 檢視檔案内容
cat file
less
既然cat有這個問題,針對比較大的檔案,我們就可以使用less指令打開某個檔案。類似vim,less可以在輸入/後進入查找模式,然後按n(N)向下(上)查找。
有許多操作,都和vim類似,你可以類比看下。
tail
大多數做服務端開發的同學,都了解這麼指令。比如,檢視nginx的滾動日志。
tail -f access.log
tail指令可以靜态的檢視某個檔案的最後n行,與之對應的,head指令檢視檔案頭n行。但head沒有滾動功能,就像尾巴是往外長的,不會反着往裡長。
tail -n100 access.log
head -n100 access.log
1.2.1 統計
sort和uniq經常配對使用。sort可以使用-t指定分隔符,使用-k指定要排序的列。
下面這個指令輸出nginx日志的ip和每個ip的pv,pv最高的前10
# 2019-06-26T10:01:57+08:00|nginx001.server.ops.pro.dc|100.116.222.80|10.31.150.232:41021|0.014|0.011|0.000|200|200|273|-|/visit|sign=91CD1988CE8B313B8A0454A4BBE930DF|-|-|http|POST|112.4.238.213
awk -F"|" '{print $3}' access.log | sort | uniq -c | sort -nk1 -r | head -n10
1.2.3 其他
grep
grep用來對内容進行過濾,帶上--color參數,可以在支援的終端可以列印彩色,參數n則輸出具體的行數,用來快速定位。
比如:檢視nginx日志中的POST請求。
grep -rn --color POST access.log
推薦每次都使用這樣的參數。
如果我想要看某個異常前後相關的内容,就可以使用ABC參數。它們是幾個單詞的縮寫,經常被使用。A after 内容後n行B before 内容前n行C count? 内容前後n行
就像是這樣:
grep -rn --color Exception -A10 -B2 error.log
diff
diff指令用來比較兩個檔案是否的差異。當然,在ide中都提供了這個功能,diff隻是指令行下的原始折衷。對了,diff和patch還是一些平台源碼的打更新檔方式,你要是不用,就pass吧。
1.3壓縮
為了減小傳輸檔案的大小,一般都開啟壓縮。linux下常見的壓縮檔案有tar、bzip2、zip、rar等,7z這種用的相對較少。
.tar 使用tar指令壓縮或解壓
.bz2 使用bzip2指令操作
.gz 使用gzip指令操作
.zip 使用unzip指令解壓
.rar 使用unrar指令解壓
最常用的就是.tar.gz檔案格式了。其實是經過了tar打包後,再使用gzip壓縮。
建立壓縮檔案
tar cvfz archive.tar.gz dir/
解壓
tar xvfz. archive.tar.gz
快去弄清楚它們的關系吧。
1.4 日常運維
開機是按一下啟動按鈕,關機總不至于是長按啟動按鈕吧。對了,是shutdown指令,不過一般也沒權限-.-!。passwd指令可以用來修改密碼,這個權限還是可以有的。
mount
mount指令可以挂在一些外接裝置,比如u盤,比如iso,比如剛申請的ssd。可以放心的看小電影了。
mount /dev/sdb1 /xiaodianying
chown
chown 用來改變檔案的所屬使用者和所屬組。
chmod 用來改變檔案的通路權限。
這兩個指令,都和linux的檔案權限777有關。
示例:
# 毀滅性的指令
chmod 000 -R /
# 修改a目錄的使用者群組為 xjj
chown -R xjj:xjj a
# 給a.sh檔案增加執行權限(這個太常用了)
chmod a+x a.sh
yum
假定你用的是centos,則包管理工具就是yum。如果你的系統沒有wget指令,就可以使用如下指令進行安裝。
yum install wget -y
systemctl
當然,centos管理背景服務也有一些套路。service指令就是。systemctl相容了service指令,我們看一下怎麼重新開機mysql服務。 推薦用下面這個。
service mysql restart
systemctl restart mysqld
對于普通的程序,就要使用kill指令進行更加詳細的控制了。kill指令有很多信号,如果你在用kill -9,你一定想要了解kill -15以及kill -3的差別和用途。
su
su用來切換使用者。比如你現在是root,想要用xjj使用者做一些勾當,就可以使用su切換。
su xjj
su - xjj
-可以讓你幹淨純潔的降臨另一個賬号,不出意外,推薦。
1.5 系統狀态概覽
登陸一台linux機器,有些指令能夠幫助你快速找到問題。這些指令涵蓋記憶體、cpu、網絡、io、磁盤等。
unameuname指令可以輸出目前的核心資訊,讓你了解到用的是什麼機器。
uname -a
ps
ps指令能夠看到程序/線程狀态。和top有些内容重疊,常用。
# 找到java程序
ps -ef|grep java
top系統狀态一覽,主要檢視。cpu load負載、cpu占用率。使用記憶體或者cpu最高的一些程序。下面這個指令可以檢視某個程序中的線程狀态。
top -H -p pid
free
top也能看記憶體,但不友好,free是專門用來檢視記憶體的。包括實體記憶體和虛拟記憶體swap。
df
df指令用來檢視系統中磁盤的使用量,用來檢視磁盤是否已經到達上限。參數h可以以友好的方式進行展示。
df -h
ifconfig
檢視ip位址,不啰嗦,替代品是ip addr指令。
ping
至于網絡通不通,可以使用ping來探測。(不包括那些禁ping的網站)
netstat雖然ss指令可以替代netstat了,但現實中netstat仍然用的更廣泛一些。比如,檢視目前的所有tcp連接配接。
netstat -ant
此指令,在找一些本地起了什麼端口之類的問題上,作用很大。
1.6 工作常用
還有一些在工作中經常會用到的指令,它們的出現頻率是非常高的 ,都是些熟面孔。
export
很多安裝了jdk的同學找不到java指令,export就可以幫你辦到它。export用來設定一些環境變量,env指令能看到目前系統中所有的環境變量。比如,下面設定的就是jdk的。
export PATH=$PATH:/home/xjj/jdk/bin
有時候,你想要知道所執行指令的具體路徑。那麼就可以使用whereis指令,我是假定了你裝了多個版本的jdk。
crontab
這就是linux本地的job工具。不是分布式的,你要不是運維,就不要用了。比如,每10分鐘提醒喝茶上廁所。
*/10 * * * * /home/xjj/wc10min
datedate指令用來輸出目前的系統時間,可以使用-s參數指定輸出格式。但設定時間涉及到設定硬體,是以有另外一個指令叫做hwclock。
xargsxargs讀取輸入源,然後逐行處理。這個指令非常有用。舉個栗子,删除目錄中的所有class檔案。
find . | grep .class$ | xargs rm -rvf
#把所有的rmvb檔案拷貝到目錄
ls *.rmvb | xargs -n1 -i cp {} /mount/xiaodianying
1.7 網絡
linux是一個多作業的網絡作業系統,是以網絡指令有很多很多。工作中,最常和這些打交道。
ssh
這個,就不啰嗦了。你一定希望了解ssh隧道是什麼。你要是想要詳細的輸出過程,記得加參數-v。
scp
scp用來進行檔案傳輸。也可以用來傳輸目錄。也有更進階的sftp指令。
scp a.txt 192.168.0.12:/tmp/a.txt
scp -r a_dir 192.168.0.12:/tmp/
wget
你想要在伺服器上安裝jdk,不會先在本地下載下傳下來,然後使用scp傳到伺服器上吧(有時候不得不這樣)。wget指令可以讓你直接使用指令行下載下傳檔案,并支援斷點續傳。
wget -c http://oracle.fuck/jdk2019.bin
mysql
mysql應用廣泛,并不是每個人都有條件用上navicat的。你需要了解mysql的連接配接方式和基本的操作,在異常情況下才能遊刃有餘。
mysql -u root -p -h 192.168.1.2
不要覺得複雜,指令是有限的,但激情無限;都會也不要驕傲,一個vim就夠折騰一輩子。捷徑就是總結,深入隻有探索。白馬過隙,終會行雲流水,手到擒來。
物是人非,年華易老。唯有時光,不會辜負。
2. 挑選一個Linux發行版
和Linux比較像的還有Unix,但如果你是一個二三十歲的小青年,你接觸到可能隻有Linux的世界了。從手機,到伺服器上廣泛使用的centos,到漂亮的桌面發行版ubuntu,甚至是風靡全球的樹莓派,到處都是linux的身影。
2.1 你需要知道這些linux曆史
知道一點相關作業系統的曆史,是能夠陶冶情操的。GNU/Linux是為了抵制一些商業公司的壟斷行為而發展起來的,凝結了一代網際網路人向往自由的心血。
和其他Unix比起來,Linux其實很年輕。直到1991年,一個叫Linus Torvalds的芬蘭年輕人才開始開發我們現在所知道的Linux核心。
Linux的吉祥物是企鵝,這個吉祥物直到1996年才确定,是以你會經常看到一些搞笑的圖檔。如果你是90後,那這隻小企鵝幾乎和你一般大,還是個年輕的小夥。
Linux的發展曆程比較的複雜。經過一次次的過關斬将,Linux走到今天确屬不易。關于其發展曆史,你可以通過下面的連結,檢視高清圖檔。20年的時間,對軟體行業來說,是一段非常漫長的時光,有多少的風光已經物是人非。
高清見圖檔(http://1t.click/aUnx) 。可以看到,linux隻占了那可憐的一小塊。這就像人類的出現,在生命的長河中,微不足道,但卻是一個質的飛躍。
你可能注意到,在前面的描述中,說的是GUN/Linux,而不僅僅是Linux。Linux本身隻是一個核心,作用有限,隻有和GNU聯合起來,擁有完整的生态才會發揮它的作用。
談到上面差別的原因,是為了記住Richard Stallman在1983年發起的GNU計劃。他同時是smalltalk語言的發明者,被公認的第二個面向對象的語言。我在早些年,還研究過一段時間。哦,他還編寫了一個巨無霸編輯器,Emacs。
隻有一個人被捧成神,他才會有能量折磨你。
針對于Linux曆史,我們不做過多介紹。下面介紹幾個經典的發行版本。
2.2 精選版本介紹
現在的Linux發行版本,已經有上千個,你要是喜歡、而且多金,你也可以做一個。如何在這其中,找到最合适的版本,是需要經過一番折騰的。很多發行版本,其實是很小衆的。
這不像是哲學領域的某些東西,真理掌握在少數人手中。隻有獲得良好發展,并得到認可的Linux發行版,才有它的價值,可以說是徹頭徹尾的實用主義。
但這東西又像女朋友,剛開始感覺風采迥異,各有千秋,到最後了解到是一樣的庸俗不堪。但有人就是喜歡Linux相關的工作,一幹就是一輩子...
我可以先說一下自己的曆程。剛開始,接觸的是紅帽redhat,當時還沒有分什麼企業版。用了一段時間以後,又切換成更穩定的slackware。但是slackware上的程式更新實在太慢了,于是又切換成readhat血統的fedora,這個版本的軟體保鮮度很高。其間,又嘗試了其他幾個linux版本,最終,在2013年前後,換成了滾動更新的archlinux,直到現在。
要我個人做個推薦的話:
1、個人使用者(技術),桌面版用ubuntu=>archlinux。
2、企業使用者,伺服器,使用centos。
2.3 主要起源
這麼多Linux版本,其實有兩條主線。debian系列和redhat系列。很多發行版本,其實是二次翻新,很多就直接拿這兩個基礎系列進行改造。正所謂:作業系統千千萬,都是帽子和大便。
debian
下面這個屎一樣的圖表,就是debian。呃呃呃,和大便隻差一個字母。
Debian計劃是一個緻力于建立一個自由作業系統的合作組織。它的特點是:穩定、安全,到現在為止,已經發展了20多年了。我們所熟悉的ubuntu,就是基于debian改進的。
redhat
紅帽是一家商業公司,涉足Linux比較早,現在對個人提供一些紅帽認證之類的證書。現在雲主機使用較多的centos,包括紅帽公司的RHEL,占據了大部分伺服器市場。近期,centos 8推出了centos stream滾動版本,看起來更像是一個正常的作業系統。
2.4 典型版本
我們看一下處于不同層次的幾個典型版本。從應用方面來說,linux有桌面、伺服器、研究用等用途。
2.4.1、ubuntu
ubuntu的出現,對Linux的推廣有不可磨滅的貢獻。它是一個易于安裝的桌面版本(也有伺服器版本),界面非常漂亮。ubuntu是基于debian系統的unstable分支修改的,包管理軟體是apt-get。
它的建立者是Mark Shuttleworth,南非企業家,世界上第二名自資的太空遊客。我想,無論是太空還是ubuntu,這都是夢想吧。
2.4.2、centos
centos是目前最流行的伺服器版本。它是RHEL源代碼再編譯的産物,主要是為了繞開一些法律問題。在包管理,甚至穩定性上,與紅帽企業版沒什麼差别。
2.4.3、archlinux
archlinux采用滾動更新的模式進行發行,盡全力提供最新的穩定版本。剛開始安裝,arch隻提供一個基本的系統,甚至連界面都沒有,對初學者不是很友好。
但是,archlinux是非常幹淨的系統。很多軟體,隻有你需要的時候才會安裝。它的軟體和理念通常都是最新的,定制化非常強,深得許多Linux愛好者的喜愛。
2.4.4、gentoo
上面的archlinux,提供了編譯後的軟體包。使用者在安裝軟體時,隻需要下載下傳、解壓即可。gentoo将這個過程更近一步,可以說更加的變态。它下載下傳的是軟體的源代碼,然後在本地進行編譯,然後安裝。
這通常非常的蛋疼,因為下載下傳、編譯會花費非常長的時間,但它有一個非常大的優點,就是穩定。
這個系統比較底層,對技能要求更多,不太推薦。
2.4.5 、LFS
LFS的全拼是“linux from scratch”,意思是從零建構一個linux系統。它有一個非常詳細的安裝文檔,教你怎樣編譯核心,編譯引導程式,編譯和配置必要的軟體。
這是一個瘋狂而必要的過程。如果你想要自己的Linux之上更上層樓,跟着文檔做一遍是受益無窮的。你需要經過多次交叉編譯,最終使用chroot指令切換到新系統進行後續操作。
想做一個自己的發行版麼?從這開始吧。
2.4.6、kali
kali linux是一個非常專業的發行版。如果你在做滲透方面的工作,将是一個非常好的選擇。
發行版的安裝包非常大,包含了常見的破解工具,滲透工具,攻擊工具。這非常的危險,我曾用它暴力破解了非常多的wifi密碼,成功的窺視了鄰居的隐私。還是非常好用的。
3. 安裝一個清爽的Linux系統
工欲善其事,必先利其器。你可能會想到買一台雲主機練練手,但那畢竟要花點銀子,我們可以自己安裝一個。我們在上面提到,目前使用最廣泛的,就是centos。不論你是自建機房,還是使用類似于阿裡雲這樣的雲端環境,大多數都會提供centos的安裝。
你可能會找到多種安裝虛拟機的方式。本小節,将使用虛拟雙網卡的方式,準備一個純潔的環境。這一小節,圖檔很多。
以阿裡雲為例,預設第一位就是CentOS,提供了從7.6版本到舊版本的多個鏡像。
3.1 下載下傳
下面的文章,我們就以CentOS 7穩定版本為基礎環境。centos很流行,是以鏡像也有很多。國内,我們從上海交大下載下傳,速度應該會快一些。
http://ftp.sjtu.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1908.iso
如果交大哪天不維護了。可以從這裡找:
http://centos.mirror.ndchost.com/7/isos/x86_64/CentOS-7-x86_64-Minimal-1908.iso
為了讓大家學到更多的知識,我們使用最小化的系統ISO。最小化的iso不到1GB,而預裝了很多軟體的dvd有4.3GB的大小。我們就用這個減肥版。
3.2 安裝Linux
要想快速學習、體驗Linux,最便捷的方式,就是使用虛拟機進行安裝。目前,最流行的虛拟機,一個是VMware,一個是VirtualBox。在MacOS上還有一個Parallels Desktop。
其中,VirtualBox免費而且跨平台,能夠滿足我們的需求。接下來,将一步步引導你進行安裝。
(1) 點選建立,開啟安裝旅程。
(2) 填寫名稱,版本。然後點選繼續。
(3)按照你的機器配置,選擇記憶體
我的機器是8GB記憶體的,就配置設定給虛拟機2GB,這個已經足夠用了。
(4) 建立一個虛拟磁盤
點選繼續後,将彈出一個對話框。我們不用多管,一直點繼續,知道對話框消失。這非常的粗暴。
(5) 接下來,點選設定。
(6) 切換到Storage選項,選擇我們下載下傳的iso
(7) 點選啟動,開始安裝。
使用方向鍵切換,使得高亮聚焦在Install CentOS 7上。點選确定,開始安裝。
(8) 彈出一個安裝界面
接下來的步驟有點多,如果我們沒有特别的介紹,那麼直接continue就ok了。
(9) 接下來,配置磁盤分區
依然保持預設,并按按鈕Done退出。
(10) 配置使用者
linux上預設的使用者名為root。接下來我們設定root使用者的密碼為123456。由于這是一個弱密碼,是以需要點選兩次确定退出。
(11) 等待安裝完畢,進行重新開機
(12) 安裝成功
3.3 聯網
這個時候,我們安裝的虛拟機,還不能聯網,無法把自己的意念傳達出去。由于我們沒有對虛拟機進行任何設定,是以使用的是預設的NAT模式。
将光标聚焦到指令行視窗,然後輸入指令dhclient。等待幾秒鐘,執行ping baidu.com測試以下網絡,可以看到能夠正常通路網絡了。
上面黑漆漆的視窗,就是我們現在的Linux界面。有人覺得很醜,就像是在玩dos,但像我這種不可救藥的人,卻覺得格外的親切。
接下來的指令,我們不會再截圖,而使用高亮的代碼塊表示。為了不至于讓人暈頭轉向,請先看下圖。
3.4 外部通路虛拟機
由于NAT模式的特點,我們的虛拟機能夠通路外網,但無法被外部發現。酒香竟怕巷子深。為了解決這個問題,我們需要再添加一塊網卡。
在做這些更改之前,需要首先關閉虛拟機。可以強制關閉機器,也可以在指令行中輸入:
shutdown -h now
虛拟機關閉後,再次點選設定,切換到網絡擴充卡頁籤。如圖,添加一個新的網絡擴充卡,擴充卡類型為Host-only Adapter。通過這塊網卡,我們的主控端就能夠通路它了。
再次啟動虛拟機,執行dhclient指令後,執行ip addr檢視主機的ip位址。可以看到,我們現在有兩塊網卡,兩個ip位址。
記錄下192打頭的網絡位址,我們會使用外部的程式,比如XShell、SecureCRT等,進行連接配接。比如,我這裡的ip位址是:192.168.99.100。不廢話,看圖。
小提示:關于虛拟網卡的網段,如果有差異。你可以在全局設定裡,改成和我一樣的。
3.5 遠端連接配接
你可能已經體驗到,通過虛拟機自帶的指令行界面進行輸入,局限性非常大。通過遠端連接配接,可以把終端界面切換到我們熟悉的操作模式,如果能夠顯示彩色的終端,那再好不過了。下面介紹幾個工具,一般的,使用xshell的居多。
Windows
- XShell 你可能在公司内,見過你的SRE同僚,運指如飛,指令字元如流水一般撒過螢幕。即使非常繁雜,難以記憶的密碼,也能瞬間輸入。他可能用的就是xshell。
- SecureCRT 比較老的一款産品,使用也較多。
- MobaXterm MobaXterm就是一單檔案純綠色軟體,下載下傳過來exe包直接運作即可,不需要任何的安裝過程。
它們都有免費版和專業版之分。無力購買的話,就找找破解版。但是注意,盜版漢化的ssh用戶端,有些别有用心的人會在軟體中植入木馬,竊取你的密碼、證書,這種情況已經發生過很多次。
MacOS
對于macos使用者來說,簡單的很。直接使用iTerm,輸入指令行即可。比如使用下面的指令連接配接我們的機器。
ssh [email protected]
Linux
唔,你都已經是Linux環境了,還折騰個啥虛拟機呢?直接用吧。
推薦使用XShell、SecureCRT、iTerm等工具,通過ssh進行遠端連接配接。對于一些指令拷貝、驗證來說,要友善快捷的多。
4. 對Linux指令行有個初步了解
萬事開頭難。面對黑漆漆的Linux視窗,要勇敢的走出第一步。不要怕輸錯了什麼,系統健壯的很。指令行通常會擁有比圖形界面更高的效率,更加重要的是它可以做自動化之類的小工具,這使得生産力産生質的飛躍。
現在,你已經安裝好了centos,并遠端連接配接上了它。我們擁有了它,但并不能了解它的脾氣。接下來,讓我們進入Linux指令行的世界。和我簽訂契約吧,少年。
本小節會使用非常詳細的演進方式,來看一下一個指令,是怎樣生成和執行的。
4.1、簡單嘗試
好啦,我們現在就在終端裡了。什麼叫做終端呢?你在很多黑客電影裡,看到的黑漆漆的界面就是,它提供了一個可以輸入字元串的互動式界面,至于那些閃光的、掃描機一樣的東西,是不存在的。
嘗試輸入些什麼吧。 比如:jdsjf。
[root@localhost ~]# jdsjf
-bash: jdsjf: command not found
我們再次把這張圖貼一下。怎麼回事?指令的輸出翻譯成中文,就是“找不到指令”的意思。什麼叫指令?就是我們上面随便輸入的字元串jdsjf。
然後,我們看下提示中其他一些有用的東西。
↓↓↓↓↓↓
bash 代表的是我們所使用的shell,shell可以認為是一個解釋器,将我們的輸入解釋成一系列可執行的指令。現在的linux發行版,最流行的就是bash解釋器,幾乎每個都預裝了它。
指令找不到,證明我們的字元串bash解釋不了。但是,Linux上一些目錄裡的檔案,是可以被預設找到的,這些目錄的集合,就叫PATH 。PATH還是一個環境變量,我們可以通過指令檢視它的尊容。
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
想要知道系統中有哪些指令,就可以看下上面這些檔案夾中,都有哪些檔案。檔案非常非常之多,但是大部分我們不會接觸。是以,xjjdog才會寫這麼個東西--聚焦那些最常用,最有用的指令,最常用的參數,最有用的場景。
指令輸出後,還有一些額外的東西,比如[root@localhost ~],這部分叫做提示符,光标會一直跳動,等待你的輸入。這部分是可以定制的,甚至可以定制的十分漂亮。
4.2、Hello World
到現在為止,我們什麼都沒得到。按照程式員的想法來說,就要實作一個hello world的程式。在終端shell裡,這個過程變得簡單,遠比寫一個java程式簡單。
[root@localhost ~]# echo "Hello World"
Hello World
如上所示,echo的意思就是輸出一些内容。後面的Hello World,就叫做參數,它們之間以空格分隔,可以接受多個參數。
[root@localhost ~]# echo "Hello World" , "Fuck 996"
Hello World , Fuck 996
以上指令能夠正常運作,證明echo是我們的終端能夠認識的一個指令。那到底這個指令是在什麼地方呢?可以使用whereis指令進行查找。
[root@localhost ~]# whereis echo
echo: /usr/bin/echo /usr/share/man/man1/echo.1.gz
指令顯示。我們的echo指令全路徑,是/usr/bin/echo,由于它處于PATH目錄中,是以能夠被識别到。
4.3、将指令加入PATH
接下來,我們把上面的指令,做成一個腳本。然後将這個腳本,放到PATH目錄中。不過先等等,我們要先給指令起個名字。
首先需要建立一個檔案。在Linux上,建立檔案使用touch指令。
[root@localhost ~]# touch jdsjf
指令執行後,什麼都沒發生,它隻是建立了一個空檔案。接下來,我們向其中添加一些内容。
[root@localhost ~]# echo "echo 'Hello World'" > jdsjf
注意符号>,它的意思是,将前面的輸出,重定向到後面的檔案中。執行完上面的指令,jdsjf 中的内容,就變成了echo 'Hello World。
接下來,我們嘗試着去執行剛才生成的指令。
[root@localhost ~]# ./jdsjf
-bash: ./jdsjf : Permission denied
我們通過相對路徑的方式,來執行剛剛生成的指令。結果,終端顯示我們并沒有這個指令的執行權限。
其實,Linux在權限控制這一方面,非常的詳細。一個檔案,有可讀、可寫、可執行三種屬性。如果想要一個檔案能夠執行,需要給它添加執行權限,這個過程是由指令chmod完成的。
[root@localhost ~]# chmod u+x jdsjf
[root@localhost ~]# ./jdsjf
Hello World
我們将在後面的章節,來詳細介紹權限方面的知識。如上所示,指令已經能正常輸出,接下來,我們把指令移動到PATH中的一個目錄。
[root@localhost ~]# mv jdsjf /usr/local/bin/
[root@localhost ~]# jdsjf
Hello World
不需要加任何的相對路徑,現在,隻需要輸入jdsjf,就可以正常輸出一串數字。我們成功的讓一個沒有任何意義的字元串,表達了它的想法。雖然我們依然是它的主宰。
你可以想一下下面這三個問題:
1、我可以自定義一個目錄,比如/root/mybin,把它加入到PATH麼?
2、我可以省略上面的touch指令,直接使用重定向生成檔案麼?
3、除了放到PATH和相對路徑,還有沒有其他的指令執行方式?
5. Linux漫遊方式
想要了解linux的基本使用方法,就要了解一個基本的事實--linux系統中,一切皆檔案。
不管是指令,還是文檔,甚至裝置,目錄,套接字,在linux上對它們的操作都是一緻對待的。許多開發驅動程式的小夥伴,會發現使用的一些函數,和讀寫檔案的沒什麼兩樣(open、close、read、write、ioctl)。今天我們所說的基本操作,針對的就是普通檔案和目錄,本小節将詳細解釋相關指令。
5.1、目前路徑
到現在為止,我們還不知道自己在系統的什麼地方。在浏覽器上,我們能夠通過導航欄上的url,了解到自己在網際網路上的具體坐标。相似的功能,是由pwd指令提供的,它能夠輸出目前的工作目錄。
pwd指令是非常非常常用的指令,尤其是在一些指令提示符設定不太友好的機器上。另外,它也經常用在shell腳本中,用來判斷目前的運作目錄是否符合需求。
有很多線上事故,都是由于沒有确認目前目錄所引起的。比如rm -rf *這種危險的指令。在執行一些高危指令時,随時确認目前目錄,是個好的習慣。
[root@localhost ~]# pwd
/root
我們使用root使用者預設登陸後,就停留在/root目錄中。Linux中的目錄層次,是通過/進行劃分的。
5.2、檔案系統使用者标準
Linux的檔案系統,從一開始就有一個規範标準。它還有一個專有縮寫名詞,叫做FHS (Filesystem Hierarchy Standard)。FHS經過多年的演進,目錄結構也越來越清晰。除了一些标準的要求,還有一些使用者之間的約定。
接下來,我們大體看一下linux上的預設目錄,對其有一個基本的感覺。
第1層第二層介紹/bin
目錄/usr/bin的軟連結/sbin
目錄/usr/sbin的軟連結/lib
目錄/usr/lib的軟連結/usr/bin存放一些常用的指令/usr/sbin存放一些管理者常用的指令/usr/lib用來存放動态庫和一些子產品檔案/sys
核心中的資料結構的可視化接口/proc
記憶體映像/run
記憶體映像/boot
存放引導程式,核心相關檔案/dev
存放一些裝置檔案,比如CD光牒/etc
用于存儲一些全局的、應用的配置檔案/var
與/var/run一樣,存放的是系統運作時需要的檔案,比如mysql的pid等/tmp
非常特殊的臨時檔案夾,斷電丢失/home/**使用者目錄,比如我的目錄是/home/xjjdog/root
root使用者的home目錄
- home 平常,我們打交道最多的目錄,就集中在自己的使用者目錄,我們可以在裡面做任何操作,比如我們現在root使用者的/root目錄。一些自己的資料,比如視訊、音頻、下載下傳的檔案,或者做測試用的一些資料資料,就可以自行在這些目錄下規劃。root使用者比較特殊,普通使用者的私人目錄都是在/home下的。
- /etc etc目錄是經常要打交道的目錄,存放了一些全局的系統配置檔案和應用配置檔案。比如你安裝了php,或者nginx,它們的配置檔案就躺在/etc目錄下的某個檔案夾裡。
- /var var目錄存放一些運作中的資料,有必須的,也有非必須的。一些黑客入侵之後,會在這裡面的某些檔案中留下痕迹,他們會着重進行清理。var目錄還是一些應用程式的預設資料存放之地,比如mysql的資料檔案。
- /tmp 目錄是一個特殊的臨時目錄,檔案在斷電以後就消失了。但這個目錄,所有的使用者,都有寫入權限,通常用來做檔案交換用。
- /proc和/sys目錄,是兩個神奇的目錄。它們兩個是一種僞檔案系統,可以通過修改其中一些檔案的狀态和内容,來控制程式的行為(修改後會直接刷到記憶體上,太酷了)。剛開始的時候,隻有proc目錄,由于裡面内容有多又亂,後面又規劃出sys目錄,用來控制核心的一些行為。如果你在調優一些系統參數,和這些檔案打交道的時間比較多。
- 還有幾個空的目錄,我們沒有列在上面的表格上。比如/srv目錄,通常會把一些web服務的資料,比如nginx的,放在這裡面。但是,這并不是強制要求的,是以我見過的/srv目錄,通常會一直是空的。同樣的,/opt目錄也是這樣一個存在,你就當它不存在就行。這都屬于使用者規劃的範疇,自定義性非常強。
- 在使用Linux系統的時候,也可以建立自己的目錄。比如,我就喜歡自己建立一個叫做/data的目錄,用來存放一些資料庫相關的内容。舉個例子,/data/mysql存放mariadb的資料,而/data/es/存放elasticsearch的索引内容。
linux上的檔案類型有很多,它們大部分都分門别類的存放在相應的目錄中,比如/dev目錄下,就是一些裝置檔案;/bin檔案下,是一些可以執行指令。通常都好記的很。
5.3、檢視檔案清單
是以,上面的表格内容,我是怎麼看到的呢,靠記憶麼?ls指令,能夠列出相關目錄的檔案資訊。可以被評為linux下最勤勞的指令标兵。
現在的終端,都能夠輸出彩色的資訊,非常的直覺。oh-my-zsh和oh-my-bash等項目,可以讓你的終端更加的漂亮。把它加入到你的研究清單裡吧。
[root@localhost /]# ls /
# 注意:ls可以接受路徑參數,你不用先跳轉,就可以輸出相關資訊
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@localhost /]# ls -l /
# 帶上 -l參數,可以檢視一些更加詳細的資訊。
total 20
lrwxrwxrwx. 1 root root 7 Nov 3 20:24 bin -> usr/bin
dr-xr-xr-x. 5 root root 4096 Nov 3 20:34 boot
drwxr-xr-x. 19 root root 3080 Nov 3 21:19 dev
drwxr-xr-x. 74 root root 8192 Nov 3 20:34 etc
drwxr-xr-x. 2 root root 6 Apr 11 2018 home
lrwxrwxrwx. 1 root root 7 Nov 3 20:24 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 20:24 lib64 -> usr/lib64
drwxr-xr-x. 2 root root 6 Apr 11 2018 media
drwxr-xr-x. 2 root root 6 Apr 11 2018 mnt
drwxr-xr-x. 2 root root 6 Apr 11 2018 opt
dr-xr-xr-x. 108 root root 0 Nov 3 21:19 proc
dr-xr-x---. 2 root root 135 Nov 4 07:53 root
drwxr-xr-x. 24 root root 740 Nov 3 21:20 run
lrwxrwxrwx. 1 root root 8 Nov 3 20:24 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Apr 11 2018 srv
dr-xr-xr-x. 13 root root 0 Nov 3 21:19 sys
drwxrwxrwt. 9 root root 4096 Nov 4 03:40 tmp
drwxr-xr-x. 13 root root 155 Nov 3 20:24 usr
drwxr-xr-x. 19 root root 267 Nov 3 20:34 var
ls最常用的,就是加參數l或者參數a。
5.3.1、詳細資訊
加上參數l,能夠看到檔案的一些權限資訊已經更新日期等。但我們還看到了一些更有意思的東西。比如:
lib -> usr/lib
上面表示的,是軟連結資訊。
就如同我們上面表格所展示的一樣,lib目錄,是/usr/lib的快捷方式,它們之中的内容,沒有什麼兩樣。
關于ls -l展示的更加詳細的内容,可以參照我下面的這張圖。我們将在了解後面小節的内容後,再次對這張圖進行回顧。
5.3.2 隐藏檔案
直接在你的/root目錄裡,執行ls -al,你會看到更多東西。這些額外的隐藏檔案,都是以.開頭,以配置檔案居多。這就是參數a的作用。
[root@localhost ~]# ls -al
total 28
dr-xr-x---. 2 root root 135 Nov 4 07:53 .
dr-xr-xr-x. 17 root root 224 Nov 3 20:28 ..
-rw-------. 1 root root 1273 Nov 3 20:28 anaconda-ks.cfg
-rw-------. 1 root root 246 Nov 4 11:41 .bash_history
-rw-r--r--. 1 root root 18 Dec 28 2013 .bash_logout
-rw-r--r--. 1 root root 176 Dec 28 2013 .bash_profile
-rw-r--r--. 1 root root 176 Dec 28 2013 .bashrc
-rw-r--r--. 1 root root 100 Dec 28 2013 .cshrc
-rw-r--r--. 1 root root 129 Dec 28 2013 .tcshrc
細心的同學,應該會注意到兩個特殊的目錄。.和..。前者表示的是目前目錄,而後者表示的是上層目錄。
使用cd指令,将在這些目錄中,自由穿梭。
小技巧:如果你對英文日期閱讀困難,可以使用ls -al --full-time檢視可讀的日期。
5.4、切換目錄
執行cd指令,可以将工作目錄切換到目标檔案夾。為了展示cd指令的效果。請在root使用者下,執行下面的指令,這将建立一個7層的目錄。
cd
mkdir -p a1/b2/c3/d4/e5/f6/{g7,g8,g9,g10}
我們使用cd指令,切換到最後一層。然後,我們使用..切換到上層目錄。
[root@localhost ~]# cd a1/b2/c3/d4/e5/f6/g7
[root@localhost g7]# pwd
/root/a1/b2/c3/d4/e5/f6/g7
[root@localhost g7]# cd ..
[root@localhost f6]# pwd
/root/a1/b2/c3/d4/e5/f6
是以,切換到上面n層目錄,隻需使用多層級的../即可。有幾個特殊的變量,需要說明一下。
- ../ 指的是上層目錄
- ../../ 指的是上兩層目錄
- ./ 指的是目前目錄
- ~ 指的是目前的使用者目錄,這是一個縮寫符号
- - 使用它,可以在最近兩次的目錄中來回切換
我們來使用指令把上面這些特殊變量驗證一下。
# 跳轉到使用者根目錄
[root@localhost tmp]# cd ~
[root@localhost ~]# pwd
/root
# 進入到第三層目錄
[root@localhost ~]# cd a1/b2/c3/
[root@localhost c3]# pwd
/root/a1/b2/c3
# 跳回到前三層目錄
[root@localhost c3]# cd ../../..
[root@localhost ~]# pwd
/root
# 跳到上次通路的目錄
[root@localhost ~]# cd -
/root/a1/b2/c3
[root@localhost c3]# pwd
/root/a1/b2/c3
# 進入目前目錄:等于什麼都沒幹
[root@localhost c3]# cd ./
[root@localhost c3]# pwd
/root/a1/b2/c3
以上就是cd指令的常用用法。現在,我們傳回頭來看一下mkdir。顧名思義,就是建立目錄的意思,但一般在工作中,都會加上-p參數,這樣就可以一次性建立多層目錄。注意mkdir後面的大括号{},可以一次性的指定多個目錄進行建立,這通常能節省很多時間。
5.5、檔案操作
使用指令行操作檔案,是非常友善的。
- touch 建立檔案
- cp 複制檔案
- mv 移動檔案
- rm 删除檔案
這四個風騷的指令,主宰着檔案資料的去向。我們依然使用上面建立的目錄,進行接下來的操作。
# 建立三個檔案
[root@localhost ~]# touch long-long-long.txt
[root@localhost ~]# touch 996.txt
[root@localhost ~]# touch icu.txt
[root@localhost ~]# ls
996.txt a1 anaconda-ks.cfg icu.txt long-long-long.txt
# 複制一個檔案
[root@localhost ~]# cp 996.txt 007.txt
[root@localhost ~]# mv long-long-long.txt short.txt
[root@localhost ~]# ls
007.txt 996.txt a1 anaconda-ks.cfg icu.txt short.txt
# 移動996.txt到a1目錄,icu.txt到a1/b2目錄
# 删除short.txt
[root@localhost ~]# mv 996.txt a1/
[root@localhost ~]# mv icu.txt a1/b2/
[root@localhost ~]# rm short.txt
rm: remove regular empty file ‘short.txt’? y
# 遞歸删除a1目錄
[root@localhost ~]# rm -rvf a1/
removed directory: ‘a1/b2/c3/d4/e5/f6/g7’
removed directory: ‘a1/b2/c3/d4/e5/f6/g8’
removed directory: ‘a1/b2/c3/d4/e5/f6/g9’
removed directory: ‘a1/b2/c3/d4/e5/f6/g10’
removed directory: ‘a1/b2/c3/d4/e5/f6’
removed directory: ‘a1/b2/c3/d4/e5’
removed directory: ‘a1/b2/c3/d4’
removed directory: ‘a1/b2/c3’
removed ‘a1/b2/icu.txt’
removed directory: ‘a1/b2’
removed ‘a1/996.txt’
removed directory: ‘a1/’
[root@localhost ~]# ls
007.txt anaconda-ks.cfg
經過一番操作以後,隻剩下了007了。除了上面基本的操作,接下來我要介紹一些更加重要的功能。
可以看到在使用rm删除檔案的時候,進行了一次提示。這是為了避免誤删除一些東西,但有時候,你需要不顯示這種提示,就可以加-f參數。f參數對于cp、mv等指令來說,同樣适用,它是force的意思。
rm -f file
cp -f file1 file2
mv -f file1 file2
另外,還有一個參數-r,這是遞歸的意思。我們的目錄和檔案,通常有多個層次,遞歸可以把操作全部作用于上面,比如上面的遞歸删除a1目錄。
# 警告:以下指令會造成嚴重後果
rm -rf /
上面的這個指令,你一定經常看到。這不是笑話,已經有很多使用者是以丢失了資料,這就是傳說中的删根,最終你将一無所有。那參數v又是幹什麼用的呢?加上它之後,可以看到指令詳細的執行過程。在平常的操作中,我一般都加上。
6.開始操作檔案
你可能已經了解到,ll -l指令的第一列,能夠顯示linux的檔案類型。請對此有一個大體的印象,因為後面的很多指令,會用到這些知識。
- - 表示普通檔案
- d 表示目錄檔案
- l 表示連結檔案,比如快捷方式
- s 套接字檔案
- c 字元裝置檔案,比如/dev/中的很多檔案
- b 表示塊裝置檔案,比如一些磁盤
- p 管道檔案
Linux上的檔案可以沒有字尾,而且可以建立一些違背直覺的檔案。比如字尾是png,但它卻是一個壓縮檔案(通常不會這麼做)。大學時,就有聰明的同學這樣藏小電影,效果很好。
檢視檔案的具體類型,可以使用file指令,它很聰明,能夠識别很多檔案格式。
[root@localhost ~]# file /etc
/etc: directory
[root@localhost ~]# file /etc/group
/etc/group: ASCII text
[root@localhost ~]# file /dev/log
/dev/log: socket
[root@localhost ~]# file /dev/log
/dev/log: socket
[root@localhost ~]# file /bin
/bin: symbolic link to `usr/bin'
本部分的操作,面向的就是ASCII text類型的,普通文本檔案。接下來,我們要建立一些檔案。然後寫入一些内容到檔案裡,以便進行後續的操作。
6.1、建立一個檔案
6.1.1、數字序列
使用重定向符,能夠直接生成檔案。下面,我要生成10到20的數字,每一個數字單獨一行,寫入一個叫做spring的檔案。巧的很,seq指令可以完成這個過程。
seq 10 20 >> spring
我們在前面提到過>的意思,是将前面指令的輸出,重定向到其他地方。在這裡,我們用了兩個>,它依然是重定向的意思,但表示的是,在原來檔案的基礎上,追加内容。
也就是程式設計語言裡的w+和a+的意思。
6.1.2、檢視内容
為了檢視檔案的生成效果,可以使用cat指令檢測。cat指令将會把檔案的内容,輸出列印到終端上。如果加上參數n,甚至可以列印行号。效果如下:
[root@localhost ~]# cat spring
10
11
12
13
14
15
16
17
18
19
20
[root@localhost ~]# cat -n spring
1 10
2 11
3 12
4 13
5 14
6 15
7 16
8 17
9 18
10 19
11 20
除了檢視檔案内容,cat指令通常用在更多的地方。隻有和其他指令聯合起來,它才會覺得生活有意義。
# 合并a檔案和b檔案到c檔案
cat a b>> c
# 把a檔案的内容作為輸入,使用管道處理。我們在後面介紹
cat a | cmd
# 寫入内容到指定檔案。在shell腳本中非常常用。我們在後面會多次用到這種寫法
cat > index.html <<EOF
<html>
<head><title></title></head>
<body></body>
</html>
EOF
由于我們的檔案不大,cat指令沒有什麼危害。但假如檔案有幾個GB,使用cat就危險的多,這隻叫做貓的小指令,會在終端上瘋狂的進行輸出,你可以通過多次按ctrl+c來終止它。
6.2、平和的檢視檔案
既然cat指令不适合操作大檔案,那一定有替換的方案。less和more就是。由于less的加載速度比more快一些,是以現在一般都使用less。它最主要的用途,是用來分頁浏覽檔案内容,并提供一些快速查找的方式。less是一個互動式的指令,你需要使用一些快捷鍵來控制它。
這次我們使用seq生成一千萬行記錄,足足有76MB大小,然後用less打開它。
[root@localhost ~]# seq 10000000 > spring
[root@localhost ~]# du -h spring
76M spring
[root@localhost ~]# less spring
關于less,一般操作如下:
- 空格 向下滾屏翻頁
- b 向上滾屏翻頁
- / 進入查找模式,比如/1111将查找1111字樣
- q 退出less
- g 到開頭
- G 去結尾
- j 向下滾動
- k 向上滾動,這兩個按鍵和vim的作用非常像
6.3、檔案頭尾
head可以顯示檔案頭,tail可以顯示檔案尾。它們都可以通過參數-n,來指定相應的行數。
[root@localhost ~]# head -n 3 spring
1
2
3
[root@localhost ~]# tail -n 3 spring
9999998
9999999
10000000
對于部分程式員來說,tail -f或許是最常用的指令之一。它可以在控制終端,實時監控檔案的變化,來看一些滾動日志。比如檢視nginx或者tomcat日志等等。通常情況下,日志滾動的過快,依然會造成一些困擾,需要配合grep指令達到過濾效果。
# 滾動檢視系統日志
tail -f /var/log/messages
# 滾動檢視包含info字樣的日志資訊
tail -f /var/log/messages | grep info
對于tail指令來說,還有一個大寫的參數F。這個參數,能夠監控到重新建立的檔案。比如像一些log4j等日志是按天滾動的,tail -f無法監控到這種變化。
6.4、查找檔案
考慮下面這個場景。我們需要找一個叫做decorator.py的檔案,這個檔案是個幽靈,可能存在于系統的任何地方。find指令,能夠勝任這次捉鬼行動。
我們使用find指令,從根目錄找起,由于系統的檔案過多,下面的指令可能會花費一段時間。
[root@localhost site-packages]# find / -name decorator.py -type f
/usr/lib/python2.7/site-packages/decorator.py
使用time指令,可以看到具體的執行時間。執行還是挺快的麼!秒出!
[root@localhost site-packages]# time find / -name decorator.py -type f
/usr/lib/python2.7/site-packages/decorator.py
real 0m0.228s
user 0m0.098s
sys 0m0.111s
find指令會查出一個路徑的集合。通常是查詢出來之後,進行額外的處理操作,一般配合xargs指令使用(xargs讀取輸入,然後逐行處理),至于find的exec參數?忘了它吧,不好用!
# 删除目前目錄中的所有class檔案
find . | grep .class$ | xargs rm -rvf
# 找到/root下一天前通路的檔案,type後面的類型參見文章開頭
find /root -atime 1 -type f
# 查找10分鐘内更新過的檔案
find /root -cmin -10
# 找到歸屬于root使用者的檔案
find /root -user root
# 找到大于1MB的檔案,進行清理
find /root -size +1024k -type f | xargs rm -f
find的參數非常非常多,記不住怎麼辦?除了常用的,其實都可以通過man指令檢視。man的操作也和vi非常的類似,輸入/EXAMPLES,會看到很多樣例。不過我覺得還是上面列出的這些指令更加的适用。
6.4.1、資料來源
在上圖中,你會看到mtime,ctime,atime類似的字樣,它們的資料來自于何處呢?接下來我們順理成章的看一下stat指令。
[root@localhost ~]# stat spring
File: ‘spring’
Size: 78888897 Blocks: 154080 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 8409203 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2019-11-04 18:01:46.698635718 -0500
Modify: 2019-11-04 17:59:38.823458157 -0500
Change: 2019-11-04 17:59:38.823458157 -0500
Birth: -
這不就是檔案屬性麼?從檔案大小,到檔案類型,甚至到最後修改、通路時間,都可以從這裡擷取。Linux檔案系統以塊為機關存儲資訊,為了找到某一個檔案所在存儲空間的位置,會用i節點(inode) 對每個檔案進行索引,你可以認為它是一個檔案指針。
- 檔案的位元組數
- 檔案擁有者user
- 檔案所屬組group
- 檔案的讀、寫、執行權限
- 檔案的時間戳
- ctime指inode上一次變動的時間
- mtime指檔案内容上一次變動的時間
- atime指檔案上一次打開的時間。
- 連結數,即有多少檔案名指向這個inode (ln指令)
- 檔案資料block的位置(具體的資料位置)
關于inode是一個比較大的話題,也是比較重要的知識點,有興趣的可以自行搜尋。我們隻需要知道這些資訊是從這裡來的就可以了。
6.4.2、小練習
如果我隻想擷取Modify這個數值,可以組合使用一下上面學到的指令。首先擷取最後三行,然後擷取首行。效果如下:
[root@localhost ~]# stat spring | tail -n 3 | head -n 1
Modify: 2019-11-04 17:59:38.823458157 -0500
下面幾個指令,效果是與上面等價的,輸出結果也是一模一樣。正所謂條條大路通羅馬,接下來,我們首先介紹一下出現頻率較高的grep。另外,我們在上面的這些指令中,多次使用了|,這是Linux中非常重要的管道概念,下面也會着重介紹。
stat spring | head -n 7 | tail -n 1
stat spring | grep Modify
stat spring | sed -n '7p'
stat spring | awk 'NR==7'
6.5、字元串比對
grep用來對内容進行過濾,帶上--color參數,可以在支援的終端可以列印彩色,參數n則用來輸出具體的行數,用來快速定位。這是一個必須要熟練使用的指令。
比如:檢視nginx日志中的POST請求。
grep -rn --color POST access.log
推薦每次都使用這樣的參數。
如果我想要看某個異常前後相關的内容,就可以使用ABC參數。它們是幾個單詞的縮寫,經常被使用。
- A after 内容後n行
- B before 内容前n行
- C 内容前後n行
就像是這樣:
# 檢視Exception關鍵字的前2行和後10行
grep -rn --color Exception -A10 -B2 error.log
#查找/usr/下所有import關鍵字,已經它們所在的檔案和行數
grep -rn --color import /usr/
6.6、管道
在上面的指令中,我們多次用到了|,這貌似可以完成一些神奇的事情。|是pipe的意思,它可以把多個指令聯系起來。通常,指令有下面的關聯方式:
- ; 順序執行,如mkdir a;rmdir a
- && 條件執行,如mkdir a && rmdir a
- || 條件執行,如mkdir a || rmdir a,後面的指令将不執行
- | 管道,前面指令的輸出,将作為後面指令的輸入
前三種的指令關聯,是非常簡單有邏輯的,非常的好了解。而管道,卻有自己的特點。
接觸過程式設計語言的都知道stdin、stdout、stderr的概念。讓我們重新組織一下針對于管道的定義:前面指令的輸出(stdin),将作為後面指令的輸入(stdout)。
我們拿一行指令來說明。
seq 20 100 | head -n 50 | tail -n 1
上面指令,将輸出69。69是個神奇的數字,它是怎麼辦到的呢?我們來一張小圖,一切就豁然開朗了。
關于輸入輸出和錯誤,linux使用一個數字進行縮寫,這在一些腳本中,甚至在一些安裝檔案中,會經常用到。
- 0 表示stdin标準輸入
- 1 表示stdout标準輸出
- 2 表示stderr标準錯誤
通過類似2>&1的文法,可以把錯誤資訊定向到标準輸出。我們用指令來證明一下。
# 錯誤資訊無法輸出到檔案
[root@localhost ~]# cat aaaaaaaaa > b
cat: aaaaaaaaa: No such file or directory
[root@localhost ~]# cat b
# 錯誤資訊被重定向了
[root@localhost ~]# cat aaaaaaaaa > b 2>&1
[root@localhost ~]# cat b
cat: aaaaaaaaa: No such file or directory
6.7、排序
在了解管道的工作原理之後,就可以介紹一下sort指令了。它通常可以和uniq(去重)指令聯合,完成一些排序、去重的操作。首先使用cat指令,生成如下内容的檔案。
cat > sort.txt <<EOF
1 11
3 22
2 44
4 33
5 55
6 66
6 66
EOF
```bash
接下來讓這兩個指令上台表演一下。sort可以使用-t指定分隔符,使用-k指定要排序的列。但是空格,是不需要做這些畫蛇添足的指定的。
```bash
# 根據第一列倒序排序
[root@localhost ~]# cat sort.txt | sort -n -k1 -r
6 66
6 66
5 55
4 33
3 22
2 44
1 11
# 統計每一行出現的次數,并根據出現次數倒序排序
# 此時,行數由7變成了6
[root@localhost ~]# cat sort.txt | sort | uniq -c | sort -n -k1 -r
2 6 66
1 5 55
1 4 33
1 3 22
1 2 44
1 1 11
注意:uniq指令,一般用在已經經過排序的結果集上。是以,很多情況需要首先使用sort指令進行排序後,再使用uniq指令。新手經常會忘記第一步,造成指令不能正常運作。
6.8、小練習
本部分,我們從檔案的屬性開始說起,了解了幾個對檔案操作的常用指令。并順便介紹了管道的概念。下面,我們來練習一下。
找到系統中所有的grub.cfg檔案,并輸出它的行數。
分析:首先需要使用find指令,找到這些檔案。然後使用xargs逐行處理。最後,使用wc指令,統計确切的行數。
[root@localhost grub2]# find / | grep grub.cfg | xargs wc -l
141 /boot/grub2/grub.cfg
輸出系統的group清單
cat /etc/group | awk -F ':' '{print $1}'
下面這個指令輸出nginx日志的ip和每個ip的pv,pv最高的前10
# 2019-06-26T10:01:57+08:00|nginx001.server.ops.pro.dc|100.116.222.80|10.31.150.232:41021|0.014|0.011|0.000|200|200|273|-|/visit|sign=91CD1988CE8B313B8A0454A4BBE930DF|-|-|http|POST|112.4.238.213
awk -F"|" '{print $3}' access.log | sort | uniq -c | sort -nk1 -r | head -n10
6.9、思考&擴充
1、Linux的終端,是如何實作彩色的文字的?我要如何輸出一個綠色的Hello World?
2、軟連結與硬連結有什麼差別?
3、了解幾個偏門但又不是非常偏的指令。
- cut 有了awk,幾乎不怎麼會用cut了
- tr
- col
- paste
- join
- split
7. 正則和進階用法
你可能遇到一些棘手的問題,通過搜尋得到想要的結果,但下次還是要通過搜尋解決問題,這種低效的手段不是我們所想要的。典型的就是一個線上運維工程師,當問題來臨時,不會給你留太多的現場學習時間。
為了達到更高效的訓練,我們要做兩件事情:第一,總結歸納;第二,觸類旁通。Linux的指令也是如此,一個問題,通常會有多種解決方式,要通過變化找出其中的共性。
這涉及到一些設計者對于規範約定俗成的遵守。一般的,你隻需要掌握一小部分指令,然後對大批指令達到了解的程度,就可以在指令行的世界裡遊刃有餘。舉個例子,你知道ls是列出檔案目錄,你就會聯想到lscpu是列出cpu資訊;lsmem是列出記憶體資訊;lsblk是磁盤資訊等。這種共性很多,比如top系列,stat系列。
7.1、輔助資訊
7.1.1、Linux檔案格式
在Linux上工作,是非常非常排斥二進制這種格式的,幾乎什麼都是可以讀寫的文本内容。大多數指令生成的結果,也都是文本檔案。這些檔案有一些特點,通常列與列都是通過空格或者<TAB>鍵分隔的。比如下面lsmem的結果,這種有規律的,有章可循的檔案,是非常容易被處理的。
[root@localhost ~]# lsmem
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000007ffffff 128M online no 0
0x0000000008000000-0x000000000fffffff 128M online yes 1
0x0000000010000000-0x0000000017ffffff 128M online no 2
0x0000000018000000-0x0000000027ffffff 256M online yes 3-4
0x0000000028000000-0x000000004fffffff 640M online no 5-9
0x0000000050000000-0x000000005fffffff 256M online yes 10-11
0x0000000060000000-0x000000007fffffff 512M online no 12-15
Memory block size: 128M
Total online memory: 2G
Total offline memory: 0B
有一大批針對于行操作的指令,同樣有一批針對于列操作的指令。然後,有兩個集大成者,叫做sed、awk。由于這兩個指令的内容非常多,我們将其列為單獨的章節。
7.1.2、指令記不住怎麼辦?
通常linux指令都十分簡單,但是有些還是有些複雜度的。比如find,ps這種指令,如果要照顧到所有的場合,可能需要非常巨大的篇幅。但是,萬一用到這種偏門的場合怎麼辦?
全面了解一下是非常有必要的,以便在使用的時候能夠喚起記憶中最淺顯的印象。然後剩下的,就可以交給類似于man的這種指令了。Linux上的每一個指令,都會有配套的幫助檔案,這遠比網絡上那些轉來轉去的資訊,正确的多。
正式介紹一下下面的兩個指令:
- man 用來顯示某個指令的文檔資訊。比如:man ls
- info 你可以認為和man是一樣的,雖然有一些能夠互補的内容。它們會在内容中進行提示的
- --help 很多指令通過參數--help提供非常簡短的幫助資訊。這通常是最有用最快捷的用例展示。如果你根本就記不住一個非常拗口的單詞,那就找找這些地方吧
注意:這些幫助資訊,僅集中在指令的作用域本身。對于它的組合使用場景,并沒有過多資訊。也就是說,它教會了你怎麼用,但并沒有告訴你用它能夠來做什麼。
這些幫助指令,一般會通過高亮關鍵字,增加閱讀的體驗。但我們可以更近一步,把幫助檔案變成彩色的。在root使用者下,執行下面的指令。然後,重新登入虛拟機。
cat >> ~/.bashrc <<EOF
function man()
{
env \\
LESS_TERMCAP_mb=\$(printf "\e[1;31m") \\
LESS_TERMCAP_md=\$(printf "\e[1;31m") \\
LESS_TERMCAP_me=\$(printf "\e[0m") \\
LESS_TERMCAP_se=\$(printf "\e[0m") \\
LESS_TERMCAP_so=\$(printf "\e[1;44;33m") \\
LESS_TERMCAP_ue=\$(printf "\e[0m") \\
LESS_TERMCAP_us=\$(printf "\e[1;32m") \\
man "\$@"
}
EOF
再次執行man指令,就可以看到彩色的資訊了。
7.1.3、TAB補全
現在,在終端裡,輸入ca,然後快速按2次<TAB>鍵盤,指令行會進入補全模式,顯示以ca打頭的所有指令。
[root@localhost ~]# ca
cacertdir_rehash cache_dump cache_repair cache_writeback ca-legacy capsh case catchsegv
cache_check cache_metadata_size cache_restore cal caller captoinfo cat catman
如果你對某個指令,隻有模糊的印象,隻記得前面的幾個字母,這個功能是極好的,指令範圍會一步步縮減。
7.2、正規表達式
為了開始下面的内容,我們首先介紹一下正規表達式。在前面的一些指令中,也可以使用這些正規表達式,比如less、grep等。
有些書籍,能夠把正規表達式寫成一本書,我們這裡僅作簡單的介紹,但足夠用了。一般的,正規表達式能用在比對上,還能夠把比對的内容拿來做二次利用。關于後者,我們在sed指令中介紹。
标志意義^行首$行尾.任意單個字元*比對0個或者多個前面的字元+1個或者多個比對?0個或者1個比對{m}前面的比對重複m次{m,n}前面的比對重複m到n次[]比對一個指定範圍内的字元[^]比對指定範圍外的任意單個字元\轉義字元[0-9]比對括号中的任何一個字元,or的作用|or,或者\b比對一個單詞。比如\blucky\b 隻比對單詞lucky
使用下面的指令建立一個檔案,我們練習一下grep指令加上E參數後的正則表現。
cat > 996 <<EOF
996: 996 is a funcking thing . which make woman as man , man as ass .
we all on the bus , bus bus on the way . 996
way to icu. icuuuuuu......
The greedy green boss rides on the pity programmer
EOF
在終端執行下面指令,注意高亮的部分即為比對到的字元串。
# 比對996開頭的行
[root@localhost ~]# cat 996 | grep -E ^996
996: 996 is a funcking thing . which make woman as man , man as ass .
# 比對996結尾的行
[root@localhost ~]# cat 996 | grep -E 996$
we all on the bus , bus bus on the way . 996
# 比對到icu和icuuuuuu
[root@localhost ~]# cat 996 | grep -E icu+
way to icu. icuuuuuu......
# 再次比對到996
[root@localhost ~]# cat 996 | grep -E [0-9]
996: 996 is a funcking thing . which make woman as man , man as ass .
we all on the bus , bus bus on the way . 996
[root@localhost ~]# cat 996 | grep -E ^[\^0-9]
we all on the bus , bus bus on the way . 996
way to icu. icuuuuuu......
The greedy green boss rides on the pity programmer
# 比對所有不包含996的行,良心指令,淚奔
[root@localhost ~]# cat 996 | grep -E -v [0-9]{3}
way to icu. icuuuuuu......
The greedy green boss rides on the pity programmer
# 比對boss和icu
[root@localhost ~]# cat 996 | grep -E boss\|icu
way to icu. icuuuuuu......
The greedy green boss rides on the pity programmer
# 比對所有行
[root@localhost ~]# cat 996 | grep -E .
996: 996 is a funcking thing . which make woman as man , man as ass .
we all on the bus , bus bus on the way . 996
way to icu. icuuuuuu......
The greedy green boss rides on the pity programmer
正規表達式非常的重要,在一些sed腳本中,awk腳本中,甚至是vim編輯器中,都會簡化你的操作。以上内容應該熟記,達到不需要查找文檔的地步。
下面有6個小問題,可以思考一下。
1、回過頭去,執行一下man cat,是否發現了一個叫做tac的指令?它是幹什麼的?
2、上面提到的stat系列,你能想象iostat大體是幹什麼用的麼?
3、grep -v是什麼意思?
4、了解一下和mv非常像的rename指令來批量修改檔案,看能否使用上面的正則。
5、有些指令如果拼寫錯誤,如何快速修正?靠搜尋麼?了解一下fuck指令。我沒有說錯。
6、下面哪種寫法表示如果cmd1成功執行,則執行cmd2指令?
- A. cmd1&&cmd2
- B. cmd1|cmd2
- C. cmd1;cmd2
- D. cmd1||cmd2
8. Linux下的壓縮
壓縮,是一件非常神奇的事情。
很久很久之前,就接觸過一些64KB大小的電影,你花半小時都看不完。事實上,這些動畫的真實容量是15GB,Warez組織把它壓縮了25萬倍。
你要是Windows系統,可以在這裡下載下傳體驗一下。但我們現在講的是Linux,很打臉是不是?
連結: https://pan.baidu.com/s/12YJQ4jsbtRr7RxoLpARTyQ
提取碼: r7sp
壓縮是件神奇的事。它能大能小,能伸能縮,在現實中很難找到這樣的東西。
為了減小傳輸檔案的大小,或者為了傳輸友善,一般都會開啟壓縮。linux下常見的壓縮檔案有tar、bzip2、zip、rar等,7z這種用的相對較少。壓縮之後的檔案,非常适合在網絡環境上傳輸。甚至,你可以認為iso檔案為一種特殊的壓縮方式。
.tar 使用tar指令壓縮或解壓.bz2 使用bzip2指令操作.gz 使用gzip指令操作.zip 使用unzip指令解壓.rar 使用unrar指令解壓.Z 使用compress,uncompress
準備工作:使用下面的指令,複制1000個檔案。
cd ~
mkdir files
cd files
seq 1000 | xargs -I {} cp /etc/group {}
使用ls,就可以看到我們剛才建立的1000個檔案。接下來,我們使用壓縮指令将它打包成一個。
# 檢視1000個檔案的總大小
[root@localhost files]# du -h .
4.0M .
# 切換到root目錄
cd ~
# 使用tar進行壓縮,壓縮後的檔案不到1MB
[root@localhost ~]# tar cvf files.tar files
[root@localhost ~]# du -h files.tar
1012K files.tar
# 使用gizp提高壓縮比,壓縮後的檔案隻有12KB
[root@localhost ~]# gzip files.tar
[root@localhost ~]# du -h files.tar.gz
12K files.tar.gz
tar和gzip一般是聯合使用的。tar指令提供了一種特殊的功能,就是可以在打包解包的同時調用其他的壓縮程式,比如:gzip,bzip2等。
下面的指令,與上面執行兩次指令後是等同的。是以,一般使用下面的方式進行操作。
[root@localhost ~]# tar cvfz files2.tar.gz files
[root@localhost ~]# du -h files2.tar.gz
12K files2.tar.gz
與之對應的,就是解壓操作。我們隻需要改動指令行中的一個字母即可:c->x。但其實,參數v和z也是可以省略的。
[root@localhost ~]# tar xvfz files2.tar.gz
我們更加常用的方式,是加上參數C,指定一個要解壓的目錄。比如下面的指令,把壓縮内容解壓到/opt目錄中。
[root@localhost ~]# tar xvfz files2.tar.gz -C /opt/
那如果我僅僅想要看下壓縮檔案中包含哪些檔案呢?這就要使用參數t。
- c 壓縮
- x 解壓
- t 檢視清單
安裝其他的
我們來看一下常用的zip和rar解壓程式有沒有安裝。
[root@localhost ~]# which unzip
/usr/bin/which: no unzip in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
[root@localhost ~]# which unrar
/usr/bin/which: no unrar in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
是以,我們的系統并沒有安裝這兩個應用。那我就使用centos的包管理工具yum安裝一下。java中的jar指令也是與zip類似的,可自行探索。
[root@localhost ~]# yum install -y zip unzip rar unrar
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.aliyun.com
...
rar不能安裝成功,是以rar檔案并不能被解壓。沒關系,我們在後面的章節把它安裝上。
現在,你會在Linux安裝tomcat了麼?
接下來,我們思考一下:
1、 經過zip壓縮的檔案,再使用gzip壓縮,容量還會減少麼?
為了驗證這個過程,可以使用dd指令,生成一個69MB大小的随機檔案。dd指令也是個神奇哦。
[root@localhost ~]# dd if=/dev/urandom of=test bs=1M count=69
69+0 records in
69+0 records out
72351744 bytes (72 MB) copied, 0.446161 s, 162 MB/s
[root@localhost ~]# du -h test
69M test
是以,回到文章最上面,我們可以随機生成一批檔案,讓壓縮效果更有意義一點。
seq 1000 | xargs -i dd if=/dev/zero of={}.xjj bs=1k count=256
2、如果已經有了檔案,tar指令是如何做到強制覆寫的?
9. Linux的權限體系
我們在最最最上面,剛接觸指令行的時候,就使用chmod指令,給普通文本檔案,賦予了執行權限。本小節将看一下使用者權限和檔案權限這兩個息息相關的概念,
9.1、添加使用者
到現在為止,我們的系統中,還孤零零的隻有這一個使用者,是時候學學女娲,捏幾個小泥人了。
首先建立兩個使用者:張三(zhang3)、李四(li4)。
[root@localhost ~]# useradd zhang3
檢視下面指令的三個輸出結果。
# 系統中多了一個叫做zhang3的組,group檔案儲存了系統的組資訊
[root@localhost ~]# tail -n1 /etc/group
zhang3:x:1000:
# 系統中多了一個叫做zhang3的使用者,shadow檔案儲存了它們的密碼。很多安全滲透就是為了拿到它進行暴力破解
[root@localhost ~]# tail -n1 /etc/shadow
zhang3:!!:18207:0:99999:7:::
# home目錄中,多了一個叫做zhang3的目錄
[root@localhost ~]# ll /home --full-time
total 0
drwx------. 2 zhang3 zhang3 83 2019-11-06 22:09:33.357165082 -0500 zhang3
接下來,給我們剛剛建立的使用者,使用passwd設定一個密碼。密碼需要輸入兩次進行确認。如果想要更改密碼,可以使用chpasswd指令。
[root@localhost ~]# passwd zhang3
Changing password for user zhang3.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
那麼如何删除一個現有的使用者呢?這是通過userdel指令實作的。加上參數f,會在其他使用者使用系統的時候,強制退出。
userdel -f zhang3
9.2、檔案權限說明
從上面的指令執行結果中,我們發現了有兩件非常有意思的東西。添加使用者後,除了在密碼檔案shadow中增加了一些内容,同時還在group檔案中添加了資訊。這涉及到使用者的兩個屬性:使用者名,組名。
一個使用者隻有一個名稱代号,但是可以有多個組。下面指令建立一個密碼為123的使用者li4,并給它追加一個叫做zhang3的組。可以看到/etc/group檔案中的資訊變更。
[root@localhost ~]# useradd -G zhang3 -p 123 li4
[root@localhost ~]# tail -n 2 /etc/group
zhang3:x:1000:li4
li4:x:1001:
好啦,接下來切換到我們的檔案權限上面。為了進行下面指令的驗證,我們首先建立一個名字叫confirm777.sh的腳本檔案。為了讓腳本對所有使用者可見,我們把它建立在/tmp目錄下。
cat > /tmp/confirm777.sh <<EOF
echo $USER
id
EOF
使用ll指令檢視檔案資訊。
[root@localhost ~]# ll /tmp/confirm777.sh --full-time
-rw-r--r--. 1 root root 13 2019-11-07 04:25:55.418254935 -0500 confirm777.sh
從ll的指令可以看出,檔案的所有者是root使用者,檔案所屬的組,也是root組,它的權限是rw-r--r--。檔案權限分為三部分。
- 所有者權限,縮寫為u。檔案的所有者所擁有的權限。也就是root使用者的權限,是rw-
- 組使用者權限,縮寫為g。檔案所屬組内所有使用者的權限。因為root組内隻有root一個使用者,是以組使用者權限是r--。
- 其他使用者權限,縮寫為o。其他不相關使用者的權限,比如我們剛建立的zhang3、li4使用者,對檔案的權限就是r--。
- 全部,縮寫為a,表示對上面三類使用者集體操作。
那rw-這些東西是什麼意思呢?
- r 表示可讀權限。read。
- w 表示可寫權限。write。
- x 表示可執行權限。execute。
- - 權限占位符,表示沒有目前權限。
注意:一個使用者擁有檔案的w權限,并不代表就可以删除檔案。w僅僅針對于檔案内容來說的。
一個檔案,有3類使用者,每類使用者,有3種權限。使用最簡單的國小乘法,我們能夠得出,一個檔案的權限位,需要3x3=9個标志位表示。
我們的檔案名稱,叫做confirm777.sh,這個名字是随便起的麼?當然不是,777在linux代表特殊的含義,它代表檔案對所有使用者具有可讀、可寫、可執行的權限。可以想象,如果每個檔案都有這樣的權限,系統将無安全可言。那這一串數字是怎麼來的呢?可以看下面的對照表。
- r 4 讀
- w 2 寫
- x 1 執行
對以上三個屬性進行任意組合,可以得到:
- 4 r-- 4+0+0
- 6 rw- 4+2+0
- 5 r-x 4+0+1
- 2 -w- 0+2+0
- 3 -wx 0+2+1
- 1 --x 0+0+1
- 7 rwx 4+2+1
9.3、檔案權限更改
下面介紹三個檔案權限相關的指令。一般常用的,就是chown和chmod。
chown 更改檔案的所有者。chgrp 更改檔案的組。chmod 更改檔案權限。
接下來,我們把confirm777.sh的所有者群組,修改成剛剛建立的使用者zhang3。
cd /tmp
[root@localhost tmp]# chown zhang3:zhang3 confirm777.sh
[root@localhost tmp]# ll confirm777.sh
-rw-r--r--. 1 zhang3 zhang3 13 Nov 7 04:25 confirm777.sh
給檔案所有者增加執行權限。然後分别切換到zhang3,li4使用者執行一下。
通過su 指令,可以切換到其他使用者,一般使用su -進行環境變量的清理;而指令id,能夠看到目前正在執行的使用者資訊。
[root@localhost tmp]# chmod u+x confirm777.sh
[root@localhost tmp]# su li4
[li4@localhost tmp]$ ./confirm777.sh
bash: ./confirm777.sh: Permission denied
[li4@localhost tmp]$ exit
exit
[root@localhost tmp]# su zhang3
[zhang3@localhost tmp]$ ./confirm777.sh
root
uid=1000(zhang3) gid=1000(zhang3) groups=1000(zhang3) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
可以看到,檔案所有者zhang3可以執行檔案,但不相關的li4,提示沒有權限。接下來,我們驗證使用者組相關的權限位。
# 去掉zhang3的執行權限
root@localhost tmp]# chmod u-x confirm777.sh
[root@localhost tmp]# ll confirm777.sh
-rw-r--r--. 1 zhang3 zhang3 13 Nov 7 04:25 confirm777.sh
# 增加zhang3組的執行權限,由于li4在zhang3組裡,它擁有權限
[root@localhost tmp]# chmod g+x confirm777.sh
[root@localhost tmp]# ll confirm777.sh
-rw-r-xr--. 1 zhang3 zhang3 13 Nov 7 04:25 confirm777.sh
# 切換到zhang3進行執行
[root@localhost tmp]# su - zhang3
[zhang3@localhost tmp]$ ./confirm777.sh
bash: ./confirm777.sh: Permission denied
[zhang3@localhost tmp]$ exit
exit
# 切換到li4進行執行
[root@localhost tmp]# su - li4
[li4@localhost tmp]$ ./confirm777.sh
root
uid=1001(li4) gid=1001(li4) groups=1001(li4),1000(zhang3) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
從指令的執行結果可以看出。這次,li4能夠執行檔案,相反的,zhang3卻不能。
我們使用chmod指令來修改檔案權限,使用的是類似于a+x這樣的英文字母。拿第一個腳本來說,初始的權限是rw-r--r--,也就是644,在這種情況下,下面的兩個腳本等效。
chmod u+x confirm777.sh
chmod 744 confirm777.sh
可以看到,第二個指令,使用的是數字樣式的權限位,多了一步人腦轉換過程。這在日常的使用中,是非常不友善的。是以,使用符号法的表示方式,能夠更加直覺,非常推薦。
為了更直覺的表現這個過程,我專門制作了一張圖。
9.4、目錄權限
這裡有一個非常有意思的地方。把檔案設定成可執行,可以把普通檔案變成腳本,目錄檔案的可執行權限是什麼鬼?有什麼意義?對檔案夾來說:
- r 表示允許讀取目錄中的檔案名,但不能進入該目錄
- w 表示允許使用者修改目錄,可以建立、遷移、删除、更名目錄下的檔案
- x 可以獲得目錄下檔案的清單,以及進入目錄,執行cd指令
關于r和x的差別,可以看下面的指令結果,仔細感受一下它們的差別。一般的,幾乎所有的目錄,都擁有執行權限,不要随意對其進行設定。
[root@localhost tmp]# su - li4
[li4@localhost ~]$ cd /tmp
[li4@localhost tmp]$ mkdir nox
[li4@localhost tmp]$ touch nox/{a,b,c,d}
[li4@localhost tmp]$ chmod a-x nox
[li4@localhost tmp]$ ls nox
ls: cannot access nox/a: Permission denied
ls: cannot access nox/b: Permission denied
ls: cannot access nox/c: Permission denied
ls: cannot access nox/d: Permission denied
a b c d
[li4@localhost tmp]$ cat nox/a
cat: nox/a: Permission denied
[li4@localhost tmp]$ chmod a+x nox
[li4@localhost tmp]$ chmod a-r nox
[li4@localhost tmp]$ ls nox
ls: cannot open directory nox: Permission denied
9.5、sticky bit
接下來,我們介紹一個比較燒腦的粘貼位。
假如你要删除一個檔案,你可以沒有這個檔案的寫權限,但是你必須要擁有這個檔案上級目錄的寫權限。如何建立一個目錄,可以讓任何人些人檔案,但是又不能删除其他使用者的檔案?這就是stick bit的作用。粘貼位一般隻用于目錄上,對檔案來說并沒有什麼用處。粘貼位一般使用t表示。
我們可以看一個典型的目錄/tmp
[root@localhost tmp]# ls -dl /tmp
drwxrwxrwt. 9 root root 4096 Nov 7 06:27 /tmp
可以看到,最後一位,顯示的是t,而不是x,意思是普通使用者不能删除其他使用者的檔案。所有使用者在/tmp目錄中,都可以随意建立檔案,但是卻删除不了其他人的檔案,即使檔案的權限是777。
[root@localhost tmp]# touch /tmp/stick
[root@localhost tmp]# chown li4:li4 /tmp/stick
[root@localhost tmp]# chmod 777 /tmp/stick
[root@localhost tmp]# su - zhang3
[zhang3@localhost ~]$ rm /tmp/stick
rm: cannot remove ‘/tmp/stick’: Operation not permitted
我們在上面建立了兩個使用者zhang3和li4,并拿它們測試了chown和chmod指令,最後介紹了粘貼位。linux比較安全的原因,就是因為有比較詳盡的權限劃分。但權限是枚雙刃劍,超權使用者一個指令就可以搞垮系統,許多隐藏的木馬,通過提權運作在不為人知的地方。
權限相關的幾個指令會經常被使用,下面舉幾個例子。
# 設定/var/lib/mysql的使用者群組為mysql
chown -R mysql:mysql /var/lib/mysql
# 設定目錄可讀可寫,能夠上傳檔案
chmod 777 /var/www/uploads
# 增加本目錄下所有sh的執行權限
chomd a+x *.sh
# 變更file為可讀可寫可執行
chmod u=rwx,g=rwx,o=rwx file
下面依然是思考時間:
1、下面這個指令,執行以後,會發生什麼情況?警告:不要執行,哪怕把000改成其他數字。
# R周遊子目錄的意思
chmod -R 000 /
2、有一天,我看到一個指令chmod u+s file,文中并沒有介紹s是什麼意思,這是什麼意思?
3、如何删除一個使用者的組?
10. 如何對磁盤進行操作?
下面的場景非常的恐怖,對有些程式員來說可以是一場噩夢。
一大早剛剛去上班,煎餅果子剛啃了一半,幾個全副武裝的警察就闖進了公司。二話不說控制住了從業人員,并守株待兔的等着魚兒來上班。
原因就是:公司涉嫌存儲和擴散非法檔案,需要查封所有的伺服器進行徹查。
這些檔案,有的簡單的放在磁盤上,有的放在檔案存儲伺服器上,有的,被切成了多片放在了不同的廉價機器上。
接下來會發生什麼,要看技術人員的水準,但估計結果并不會太好。
在上一小節,我們建立了兩個普通使用者,這兩個使用者沒什麼本事,和預設的使用者root比起來,它們的權限就小得多。除了自己目錄下的檔案,其他的,它幾乎都沒有權限去修改。
這些檔案,肯定是要存在磁盤上的。對磁盤的管理,有非常多的指令,這一小節的内容,對于系統管理者來說,經常使用;但對于開發來說,就要求比較低一些。因為開發隻需要知道小電影存在什麼地方了,不需要知道小電影是怎麼存的。
那定罪的時候,運維和程式員,到底是誰的鍋更大一些?其實是個悖論。運維人員在發呆的時候,腦子裡回憶起了下面的知識。
10.1.添加新硬碟
你要是一個系統管理者,甚至是一個上了雲的系統管理者,現在買了一塊aws的擴充盤,它是不能被使用的。需要經過格式化挂載以後,才能投入生産。
還記得在安裝系統的時候麼?其中有一步,需要對虛拟機的磁盤,進行劃分,我們直接采用預設的方式。不過現在已經改不了了,它已經是過去式了。
為了模拟對磁盤的管理,我們需要首先給虛拟機新加一塊虛拟磁盤。首先,使用shutdown -h now指令關閉機器,進行下面的操作。
1、 進入settings選項,然後切換到storage,添加磁盤
2、 點選建立一塊磁盤
3、 選擇VDI
4、 動态擴容,用多少擴多少
5、 我們建立一塊2GB大的,叫做disk2的磁盤
啟動機器。遠端連接配接192的ip,别忘了執行dhclient指令。
首先使用fdisk看一下目前的磁盤狀況。
root@localhost ~]# fdisk -l
Disk /dev/sda: 8589 MB, 8589934592 bytes, 16777216 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000c2410
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 16777215 7339008 8e Linux LVM
Disk /dev/sdb: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-root: 6652 MB, 6652166144 bytes, 12992512 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/mapper/centos-swap: 859 MB, 859832320 bytes, 1679360 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
從指令的結果,我們看到了有兩塊磁盤。/dev/sda和/dev/sdb,其中sda已經被配置設定,已經被我們的檔案系統所占用。現在,回憶一下/dev目錄的用途,在這個目錄下,存放了一些裝置檔案,假如我們再添加一塊磁盤,它的句柄就應該是sdc (sd*)。
在這整塊磁盤能夠被使用之前,我們需要對它進行三次操作。
- 磁盤分區
- 磁盤格式化
- 磁盤挂載
10.2.分區
對磁盤分區依然是fdisk指令,以下指令,将進入互動模式。在互動模式中,輸入n建立分區。由于我們的磁盤隻有2GB,是以隻建立一個分區就好。根據向導,一路确定向下,最後,輸入w确定寫入分區表,同時退出指令互動。
再次執行fdisk -l,可以看到已經多了一塊2gb大小的分區。
[root@localhost ~]# fdisk /dev/sdb
...
[root@localhost ~]# fdisk -l
...
Device Boot Start End Blocks Id System
/dev/sdb1 2048 4194303 2096128 83 Linux
...
10.3.格式化
在指令行,輸入mkfs,然後按<TAB>進行補全,将會顯示一批指令。
[root@localhost ~]# mkfs.
mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4 mkfs.minix mkfs.xfs
這批指令,都可以對磁盤進行格式化。目前,最常用的磁盤格式是ext4。但我們并沒有找到windows作業系統的FAT以及NTFS等格式,但它們在概念上是等同的。
下面介紹一下Linux下常用的磁盤格式。
- btrfs GPL授權。是為了替換ext系統而發起的。不熟悉,不過多評價。
- cramfs 門針對閃存設計的隻讀壓縮的檔案系統,其容量上限為256M,采用zlib壓縮,很少用
- ext2 ext的早先版本。
- ext3 ext2的改進。
- ext4 使用最多。如果對其他的不熟悉,老老實實用ext4吧。
- minix 比較古老,也不常用。
- xfs XFS 檔案系統是擴充檔案系統的一個擴充,是 64 位高性能日志檔案系統。centos7.0開始的預設檔案系統。
我們就錄鄉随俗,将磁盤給格式化成xfs。
[root@localhost ~]# mkfs.xfs /dev/sdb1
注意:如果想要把磁盤格式化成fat32的格式,需要安裝一個軟體。
yum install dosfstools -y
10.4.挂載
最後一步,是使用mount指令挂載磁盤。我們把它挂載到/data目錄。
df指令能夠看到系統的磁盤使用狀況,參數h是human的意思,以比較容易讀的方式展現資訊;lsblk則以另一個角度檢視系統磁盤挂載情況。
[root@localhost ~]# mkdir /data
[root@localhost ~]# mount /dev/sdb1 /data
[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 908M 0 908M 0% /dev
tmpfs 920M 0 920M 0% /dev/shm
tmpfs 920M 8.6M 911M 1% /run
tmpfs 920M 0 920M 0% /sys/fs/cgroup
/dev/mapper/centos-root 6.2G 1.4G 4.9G 22% /
/dev/sda1 1014M 149M 866M 15% /boot
tmpfs 184M 0 184M 0% /run/user/0
/dev/sdb1 2.0G 33M 2.0G 2% /data
root@localhost ~]# lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINT
sda
├─sda1 xfs ac3a3ce8-6ab1-4c0b-91c8-b4e617f0dfb4 /boot
└─sda2 LVM2_member 3GzmOd-TUc1-p2ZN-wT5q-ttky-to9l-PF495o
├─centos-root xfs 9f86f663-060a-4450-90f9-3005ad9c5d92 /
└─centos-swap swap cf8709b0-b0ab-4d44-a23e-ad76f85efad6 [SWAP]
sdb
└─sdb1 xfs 0a7c861c-1a31-45b3-bf37-c72229f35704 /data
為了能夠在開機的時候加載磁盤,我們需要修改/etc/fstab檔案。這種檔案修改的時候一定要小心,否則會造成系統無法啟動。
[root@localhost ~]# echo "/dev/sdb1 xfs defaults 0 0" >> /etc/fstab
[root@localhost ~]# cat /etc/fstab
/dev/mapper/centos-root / xfs defaults 0 0
UUID=ac3a3ce8-6ab1-4c0b-91c8-b4e617f0dfb4 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdb1 xfs defaults 0 0
10.5.交換分區
由于記憶體的容量有限,現在的作業系統,都會使用磁盤模拟一個虛拟記憶體區域,用于緩沖一些資料。由于磁盤的速度和記憶體不可同日而語,通常會造成應用程式的卡頓。卡歸卡,應用程序卻可以是以苟延殘喘,續命。
swap分區,即交換區,系統在實體記憶體不夠時,與swap進行交換。即當系統的實體記憶體不夠用時,把硬碟中一部分空間釋放出來,以供目前運作的程式使用。當那些程式要運作時,再從swap分區中恢複儲存的資料到記憶體中。
現代網際網路公司,一般對接口的響應時間有比較高的要求,swap分區一般是禁用的。關于swap,有下面幾個相關的指令。
# 制作交換分區
[root@localhost ~]# mkswap /dev/sdb1
# 禁用所有交換分區
[root@localhost ~]# swapoff -a
# 啟用交換分區
[root@localhost ~]# swapon
10.6 使用dd指令進行備份
下面的指令,将直接備份磁盤A到磁盤B。
# dd if=/dev/sda of=/dev/sdb
在上面的指令中,if代表輸入的檔案,of代表輸出的檔案。根據Linux下一切皆檔案的原理,這裡的檔案指的就是裝置。
dd指令還可以将整個磁盤打包成一個鏡像檔案。比如下面的指令。
# dd if=/dev/hda of=~/hdadisk.img
當然,恢複磁盤的時候,也是相當簡單的,我們隻需要逆向操作就可以了。
# dd if=hdadisk.img of=/dev/hda
End
這篇文章有3萬字,經曆了多個版本的整理,有小夥伴已經拿着它作為了公司的教育訓練資料。到現在為止,你已經對Linux的指令行有了比較客觀的了解
本文轉載自小姐姐的味道