shell
目錄
- Shell簡介
- Shell常用命令
- Shell里面的括號
- Shell里面的單引號和雙引號
- Shell標(biāo)準(zhǔn)輸出屎飘、標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)錯誤輸出
Shell簡介
確認(rèn)當(dāng)前終端tty
使用的Shell
類型:
方法一:
ps |grep $$|awk '{print $4}'
方法二:
echo $SHELL
Shell(Unix Shell)
是一種命令行解釋器,是Unix
操作系統(tǒng)下最傳統(tǒng)的人機(jī)接口押桃。 Shell
腳本是解釋執(zhí)行的唱凯,不需要編譯磕昼,和大部分的編程語言很相似漫雕,也有基本的變量和流程控制語句浸间。我們平時使用Shell
有兩種方式:
- 輸入命令魁蒜,執(zhí)行,這種方式稱為交互式(
Interactive
)仿野; - 批處理(
Batch
)方式葫哗,用戶事先寫好Shell
腳本文件劣针,然后順序執(zhí)行腳本中的命令捺典。
第一個Shell
環(huán)境是Thompson Shell
,在貝爾實(shí)驗(yàn)室開發(fā)并于1971年發(fā)布擎浴。
現(xiàn)代Shell
最突出的祖先是被稱為sh
的BourneShell
贮预,這是以在AT&T
工作的創(chuàng)始人Stephen Bourne
命名的滑频。
Shell
一直在基于這個概念误趴,不斷添加各種新功能枣申,演變出很多種的Shell
忠藤。
例如尖阔,很早版本的OS X
中使用的是:
-
tcsh
作為默認(rèn)的Shell
介却。這是由csh(C shell)
齿坷,一種類似C
語言的Shell
演變而來。
在OS X 10.3
版與10.4
版之后遂蛀,默認(rèn)的Shell
是:
-
bash
李滴,由GNU
開發(fā)悬嗓。
現(xiàn)在macOS
中,默認(rèn)的Shell
變成了zsh
周瞎。這是一種由Paul Falstad
于1990年開發(fā)的酱讶。它是一個Bourne
式Shell
泻肯,它使用bash
和previous shell
的特性灶挟,并添加了更多的特性:
- 拼寫檢查功能
- 內(nèi)置的編程特性
- 友好的交互
與此同時,macOS
還提供了很多其他種類的Shell
:
.bashrc惕医、.bash_profile和.zshrc作用與區(qū)別
在使用命令行工具時抬伺,我們可能會遇到一些教程沛简,可能需要你把一些配置寫入到.bashrc
椒楣、.bash_profile
或者.zshrc
等捧灰。那么這幾個文件到底有什么作用和區(qū)別毛俏?
首先,從文件名稱判斷.bashrc
阀溶、.bash_profile
是給Bash
來使用的。而.zshrc
是給zsh
來使用的永品。
交互式登錄和非登錄Shell
當(dāng)調(diào)用Shell
時,Shell
從一組啟動文件中讀取信息并執(zhí)行命令炕桨。讀取什么文件就取決于Shell
是作為交互式登錄還是非登錄調(diào)用谋作。
換言之,Shell
分為交互式的或非交互式的:
交互式
Shell
是讀取和寫入到用戶終端的Shell
程序奈惑,用戶在終端上輸入命令肴甸,并在回車后立即執(zhí)行。非交互式
Shell
是與終端不相關(guān)的Shell
程序庶柿,例如執(zhí)行腳本時浮庐。
交互式Shell
可以是登錄Shell
审残,也可以是非登錄Shell
搅轿。
當(dāng)用戶通過ssh
或本地遠(yuǎn)程登錄到終端時既穆,或者使用--login
選項(xiàng)啟動時循衰,將調(diào)用登錄shell
会钝。
當(dāng)作為交互式登錄Shell
調(diào)用時迁酸,Bash
會先查找/etc/profile
文件,如果該文件存在串远,它將運(yùn)行文件中列出的命令澡罚。然后,搜索
~/.bash_profile
铛铁,~/.bash_login
以及~/.profile
文件括眠,順序讀取哺窄。
當(dāng)Bash
作為交互式非登錄shell
調(diào)用時,會讀取~/.bashrc
生年。
所以說档叔,.bashrc
和.bash_profile
之間的區(qū)別是衙四,.bash_profile
當(dāng)Bash
作為交互式登錄shell
調(diào)用時被讀取并執(zhí)行传蹈,而.bashrc
對于交互式非登錄shell
被執(zhí)行。
大多數(shù)Linux/Unix
發(fā)行版都使用~/.profile
代替~/.bash_profile
咙冗。~/.profile
所有shell
都讀取該文件灾搏,而~/.bash_profile
只有Bash
才會讀取該文件确镊。
~/.zshrc
是zsh
的交互式shell
的用戶配置拷肌。
對于Bash
添忘,它們的工作方式如下:
- 讀取適當(dāng)?shù)膬?nèi)容搁骑,執(zhí)行
A
仲器,然后執(zhí)行B
乏冀,然后執(zhí)行C
,依此類推洋只。B1
辆沦,B2
昼捍,B3
表示僅執(zhí)行找到的那些文件中的第一個。
+----------------+-----------+-----------+------+
| |Interactive|Interactive|Script|
| |login |non-login | |
+----------------+-----------+-----------+------+
|/etc/profile | A | | |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc| | A | |
+----------------+-----------+-----------+------+
|~/.bashrc | | B | |
+----------------+-----------+-----------+------+
|~/.bash_profile | B1 | | |
+----------------+-----------+-----------+------+
|~/.bash_login | B2 | | |
+----------------+-----------+-----------+------+
|~/.profile | B3 | | |
+----------------+-----------+-----------+------+
|BASH_ENV | | | A |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
|~/.bash_logout | C | | |
+----------------+-----------+-----------+------+
對于zsh
肢扯,它們的工作方式如下:
? 讀取適當(dāng)?shù)膬?nèi)容妒茬,執(zhí)行A
,然后執(zhí)行B
蛛株,然后執(zhí)行C
笋粟,依此類推尝盼。
+----------------+-----------+-----------+------+
| |Interactive|Interactive|Script|
| |login |non-login | |
+----------------+-----------+-----------+------+
|/etc/zshenv | A | A | A |
+----------------+-----------+-----------+------+
|~/.zshenv | B | B | B |
+----------------+-----------+-----------+------+
|/etc/zprofile | C | | |
+----------------+-----------+-----------+------+
|~/.zprofile | D | | |
+----------------+-----------+-----------+------+
|/etc/zshrc | E | C | |
+----------------+-----------+-----------+------+
|~/.zshrc | F | D | |
+----------------+-----------+-----------+------+
|/etc/zlogin | G | | |
+----------------+-----------+-----------+------+
|~/.zlogin | H | | |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
| | | | |
+----------------+-----------+-----------+------+
|~/.zlogout | I | | |
+----------------+-----------+-----------+------+
|/etc/zlogout | J | | |
+----------------+-----------+-----------+------+
確認(rèn)當(dāng)前是登錄還是非登錄shell
在tty
中執(zhí)行echo $0
蕾哟,輸出的Shell
如果前面帶-
琼富,說明是登錄Shell
。
配置建議
- bash:
- 將配置選項(xiàng)放到
~/.bashrc
中,然后在~/.bash_profile
中通過source
調(diào)用。
- zsh:
- 建議仍然將配置選項(xiàng)放到
~/.bashrc
,~/.bash_profile
中通過source
調(diào)用氧枣,最后在~/.zshrc
中source
調(diào)用~/.bash_profile
烧董。
常用命令參考
ag命令
ag
超快的文件搜索工具,與grep
相比喘先,搜索速度更快。
c++filt命令
c++filt
命令可用于解析C++
和Java
中被修飾的符號次酌,比如變量與函數(shù)名稱。
tree命令
tree
命令以樹狀圖列出目錄的內(nèi)容盒刚。
cp命令
cp
是copy
的縮寫趾断,cp
命令用于復(fù)制文件/文件夾。
參數(shù):
-a, --archive 等于-dR --preserve=all--backup[=CONTROL 為每個已存在的目標(biāo)文件創(chuàng)建備份
-b 類似--backup 但不接受參數(shù)--copy-contents 在遞歸處理是復(fù)制特殊文件內(nèi)容
-d 等于--no-dereference --preserve=links
-f, --force 如果目標(biāo)文件無法打開則將其移除并重試(當(dāng) -n 選項(xiàng)存在時則不需再選此項(xiàng))
-i, --interactive 覆蓋前詢問(使前面的 -n 選項(xiàng)失效)
-H 跟隨源文件中的命令行符號鏈接
-l, --link 鏈接文件而不復(fù)制
-L, --dereference 總是跟隨符號鏈接
-n, --no-clobber 不要覆蓋已存在的文件(使前面的 -i 選項(xiàng)失效)
-P, --no-dereference 不跟隨源文件中的符號鏈接
-p 等于--preserve=模式,所有權(quán),時間戳--preserve[=屬性列表 保持指定的屬性
(默認(rèn):模式,所有權(quán),時間戳),如果可能保持附加屬性:環(huán)境、鏈接、xattr 等
-R, -r, --recursive 復(fù)制目錄及目錄內(nèi)的所有項(xiàng)目
-t --target-directory=DIRECTORY 將所有源文件拷貝到目標(biāo)目錄
-T, --no-target-directory 目標(biāo)為文件而不是文件夾
ln命令
所謂的鏈接(link
),我們可以將其視為檔案的別名阔籽,而鏈接又可分為兩種:
硬鏈接(
hard link
),意思是一個檔案可以有多個名稱完残;
a. 硬鏈接,以文件副本的形式存在鸥诽。但不占用實(shí)際空間上真;
b. 不允許給目錄創(chuàng)建硬鏈接九巡;
c. 硬鏈接只有在同一個文件系統(tǒng)中才能創(chuàng)建;軟鏈接(
symbolic link
),意思是產(chǎn)生一個特殊的檔案,該檔案的內(nèi)容是指向另一個檔案的位置。
a. 軟鏈接多望,以路徑的形式存在颅痊。類似于快捷方式;
b. 軟鏈接可以跨文件系統(tǒng),硬鏈接不可以;
c. 軟鏈接可以對一個不存在的文件名進(jìn)行鏈接;
d. 軟鏈接可以對目錄進(jìn)行鏈接栓袖。
sed命令
通常要進(jìn)行文本處理,sed
是一個非常強(qiáng)大的文本處理命令工具批旺。 配合正則表達(dá)式可以進(jìn)行文本搜索坯门、替換、插入喳逛、刪除等操作曙砂。處理時末荐,把當(dāng)前處理的行存儲在臨時緩沖區(qū)中墩新,稱為模式空間(pattern space
)蝴乔,接著用sed
命令處理緩沖區(qū)中的內(nèi)容,處理完成后驮樊,把緩沖區(qū)的內(nèi)容送往屏幕薇正。接著處理下一行片酝,這樣不斷重復(fù),直到文件末尾挖腰。文件內(nèi)容并沒有改變雕沿。
grep
grep
命令全稱是Global Regular Expression Print
,是一種強(qiáng)大的文本搜索工具猴仑,它能使用正則表達(dá)式搜索文本审轮,并把匹配的行打印出來。
主要參數(shù):
ls命令
ls
命令用來顯示目標(biāo)列表辽俗。
drwxr-xr-x 2 root root 48 2020-11-27 13:34 test/
第一個欄位疾渣,表示文件的屬性。件基本上分為三個屬性:可讀(r
)崖飘,可寫(w
)榴捡,可執(zhí)行(x
)。數(shù)字表示:1表示可執(zhí)行
權(quán)限朱浴,2表示可寫
權(quán)限吊圾,4表示可讀
權(quán)限。
第一個字母表示文件類型:
-
-
翰蠢,普通文件项乒。 -
d
,目錄梁沧,是dirtectory
的縮寫檀何。 -
l
,符號鏈接廷支。 -
b
埃碱,塊設(shè)備文件。 -
c
酥泞,字符設(shè)備文件砚殿。
緊接著的3*3
個字符分3
組,各指示此文件的讀芝囤、寫似炎、執(zhí)行權(quán)限,對于owner
悯姊、group
羡藐、others
而言。
因?yàn)?code>Linux/Unix是多用戶多任務(wù)系統(tǒng)悯许,所以一個文件可能同時被許多人使用仆嗦,所以我們一定要設(shè)好每個文件的權(quán)限,其文件的權(quán)限位置排列順序是(以-rwxr-xr-x
為例):
rwx(Owner)r-x(Group)r-x(Other)
第二個欄位先壕,表示文件個數(shù)瘩扼。如果是文件的話谆甜,那這個數(shù)目自然是1了,如果是目錄的話集绰,那它的數(shù)目就是該目錄中的文件個數(shù)了规辱。
第三個欄位,表示該文件或目錄的擁有者栽燕。若使用者目前處于自己的`Home`,那這一欄大概都是它的賬號名稱罕袋。
第四個欄位,表示所屬的組(`group`)碍岔。每一個使用者都可以擁有一個以上的組浴讯,不過大部分的使用者應(yīng)該都只屬于一個組,只有當(dāng)[系統(tǒng)管理員]希望給予某使用者特殊權(quán)限時蔼啦,才可能會給他另一個組兰珍。
第五欄位,表示文件大小询吴。文件大小用`byte`來表示,而空目錄一般都是`1024byte`亮元,當(dāng)然可以用其它參數(shù)使文件顯示的單位不同猛计,如使用`ls –k`就是用`kb`顯示一個文件的大小單位,不過一般我們還是以`byte`為主爆捞。
第六個欄位奉瘤,表示最后一次修改時間。以“月煮甥,日盗温,時間”的格式表示,如`Aug 15 5:46`表示`8月15日早上5:46分`成肘。
第七個欄位卖局,表示文件名。我們可以用`ls –a`顯示隱藏的文件名双霍。
`–rwxr-xr-x`轉(zhuǎn)換成權(quán)限數(shù)字為755砚偶。即:
1. `rwx`即4+2+1=7;
2. `r-x`即4+1=5洒闸;
3. `r-x`即4+1=5染坯。
## `stat`命令
`stat`命令用于顯示文件或文件系統(tǒng)的詳細(xì)信息。在顯示文件信息時丘逸,比`ls`命令更加詳細(xì)单鹿。
參數(shù):
-L, --dereference: 跟隨符號鏈接解析原文件而非符號鏈接;
-f, --file-system: 顯示文件所在文件系統(tǒng)信息而非文件信息深纲;
-c,--format=FORMAT: 以指定格式輸出仲锄,而非默認(rèn)格式劲妙;
--printf=FORMAT: 以指定格式輸出,而非默認(rèn)格式昼窗。與--format作用類似是趴,但可以解釋反斜杠轉(zhuǎn)義字符,比如換行符\n澄惊;
-t, --terse: 簡潔模式輸出唆途,只顯示摘要信息;
--help: 顯示幫助信息掸驱;
--version: 顯示版本信息肛搬。
顯示文件信息可用格式控制符如下:
%a:以八進(jìn)制顯示訪問權(quán)限
%A:以可讀形式顯示訪問權(quán)限
%b:顯示占有塊數(shù)
%B:顯示每一塊占有的字節(jié)數(shù)
%C:SELinux security context string
%d:十進(jìn)制顯示文件所在設(shè)備號
%D:十六進(jìn)制顯示文件所在設(shè)備號
%f:十六進(jìn)制顯示文件類型
%F:文件類型。Linux下文件類型主要分為普通文件毕贼、目錄温赔、字符設(shè)備文件、塊設(shè)備文件鬼癣、符號鏈接文件陶贼、套接字等
%g:文件所有者組ID
%G:文件所有者組名稱
%h:文件硬鏈接數(shù)
%i:inode號
%m:文件所在磁盤分區(qū)掛載點(diǎn),比如/data
%n:文件名稱
%N:單引號括起來的文件名稱待秃,如果是軟鏈接拜秧,則同時顯示指向的文件名稱
%o:optimal I/O transfer size hint
%s:實(shí)際文件大小,單位字節(jié)
%t:major device type in hex, for character/block device special files
%T:minor device type in hex, for character/block device special files
%u:所有者用戶ID %U:所有者用戶名稱
%w:文件創(chuàng)建時間章郁,輸出-表示無法得知
%W:文件創(chuàng)建時間枉氮,輸出Unix時間戳,0表示無法得知
%x:可讀形式輸出最后訪問時間atime
%X:Unix時間戳輸出最后訪問時間atime
%y:可讀形式輸出最后修改時間mtime
%Y:Unix時間戳輸出后修改時間mtime
%z:可讀形式輸出最后狀態(tài)改變時間ctime
%Z:Unix時間戳輸出最后狀態(tài)改變時間ctime
顯示文件系統(tǒng)信息可用格式控制符有:
%a:非超級用戶可使用的自由block數(shù)
%b:文件系統(tǒng)總block數(shù)
%c:文件系統(tǒng)總文件節(jié)點(diǎn)數(shù)
%d:可用文件節(jié)點(diǎn)數(shù)
%f:可用文件block數(shù)
%i:十六進(jìn)制文件系統(tǒng)ID
%l:最大文件名稱長度
%n:文件名稱
%s:一個塊的大小暖庄,單位字節(jié)(for faster transfers)
%S:一個塊的基本大小聊替,單位字節(jié)(用于統(tǒng)計block的數(shù)量)
%t:十六進(jìn)制輸出文件系統(tǒng)類型
%T:可讀形式輸出文件系統(tǒng)類型
Shell
里面的括號
-
${a}
:變量a
的值, 在不引起歧義的情況下可以省略大括號培廓。 -
$(cmd)
:命令替換惹悄, 和cmd
效果相同。 -
$((exp))
:增強(qiáng)括號的用法和expr exp
效果相同肩钠, 計算數(shù)學(xué)表達(dá)式exp
的數(shù)值,俘侠,其中exp
只要符合C
語言的運(yùn)算規(guī)則即可,甚至三目運(yùn)算符和邏輯表達(dá)式都可以計算蔬将∫伲可以省略$
。比如:
for((i=0;i<5;i++))
# 如果不使用雙括號
for i in seq 0 4
for i in {0..4}
if (($i<5))
# 如果不使用雙括號
if [ $i -lt 5 ]
-
(cmd1;cmd2;cmd3)
新開一個子shell
順序執(zhí)行命令cmd1
霞怀、cmd2
惫东,cmd3
, 各命令之間用分號隔開,最后一個命令后可以沒有分號. -
{ cmd1;cmd2;cmd3;}
: 在當(dāng)前shell
順序執(zhí)行命令cmd1
廉沮、cmd2
和cmd3
颓遏。 各命令之間用分號隔開,最后一個命令后必須有分號滞时,第一條命令和左括號之間必須用空格隔開叁幢。
Shell
里面的中括號(包括[]
與[[]]
)可用于一些條件的測試:
- 算術(shù)比較,比如一個變量是否為0:
[ $var -eq 0 ]
坪稽。 - 文件屬性測試曼玩,比如一個文件是否存在:
[ -e $var ]
。 是否是目錄:[ -d $var ]
窒百。 -
[[]]
:字符串比較黍判,增強(qiáng)方括號用法,雙括號中的表達(dá)式可以使用&&
篙梢、||
顷帖、<
、>
等語法渤滞。比如:
# 比較兩個字符串是否相同
[[ $var1 = $var2 ]]
if [[ $a != 1 && $a != 2 ]]
# 如果不使用[[]]
if [ $a -ne 1] && [ $a != 2 ]
if [ $a -ne 1 -a $a != 2 ]
對{}
和()
而言贬墩,括號中的重定向符只影響該條命令, 而括號外的重定向符影響到括號中的所有命令.
Shell里面的單引號和雙引號
首先,單引號和雙引號妄呕,都是為了解決中間有空格的問題陶舞。
因?yàn)榭崭裨?code>shell中作為一個很典型的分隔符,比如string1=this is astring
趴腋,這樣執(zhí)行就會報錯。為了避免這個問題论咏,因此就產(chǎn)生了單引號和雙引號优炬。他們的區(qū)別在于荒给,單引號將剝奪其中的所有字符的特殊含義醋奠,而雙引號中的 $
(參數(shù)替換)和反引號(命令替換與$()
作用一樣)是例外裤唠。所以篙螟,兩者基本上沒有什么區(qū)別恰响,除非在內(nèi)容中遇到了參數(shù)替換符$和命令替換符反引號治专。
Shell標(biāo)準(zhǔn)輸出竞穷、標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)錯誤輸出
標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤輸出可以將內(nèi)容重定向輸出到指定的設(shè)備(如打印機(jī))或文件中吴藻,
標(biāo)準(zhǔn)輸入可以使用文件或其他輸入替換手動輸入贯吓。
- 標(biāo)準(zhǔn)輸入(
stdin
):代碼為0懈凹,符號:< 或者<<
; - 標(biāo)準(zhǔn)輸出(
stdout
):代碼為1悄谐,符號:>或者>>
介评; - 標(biāo)準(zhǔn)錯誤輸出(
stderr
):代碼為2,符號:2>或者2>>
。
單箭頭和雙箭頭的區(qū)別:
-
對于輸出:
- 單箭頭:當(dāng)指定的文件不存在時们陆,創(chuàng)建新文件寫入數(shù)據(jù)寒瓦;當(dāng)文件存在時,清空原文件的內(nèi)容寫入數(shù)據(jù)坪仇。
- 雙箭頭:當(dāng)指定的文件不存在時杂腰,創(chuàng)建新文件寫入數(shù)據(jù);當(dāng)文件存在時椅文,在原件內(nèi)容的最后追加寫入數(shù)據(jù)喂很。
-
對于輸入:
- 單箭頭:將文件或其他輸入作為標(biāo)準(zhǔn)輸入。(
<
的左邊必須是命令雾袱,<
右邊的輸入內(nèi)容作為命令的輸入)恤筛。 - 雙箭頭:結(jié)束輸入。
- 單箭頭:將文件或其他輸入作為標(biāo)準(zhǔn)輸入。(
將標(biāo)準(zhǔn)輸出和錯誤輸出重定向到一個文件上:
- 將
stdin
和stderr
無序輸出到one.log
:
grep "Cat" file.log > one.log 2>one.log
- 將
stdin
和stderr
序有輸出到one.log
:
#首先stdin重定向到one.log芹橡,然后使用2>&1表示stderr重定向至stdin毒坛,stderr在stdin之后輸入到one.log中
grep "Cat" file.log > one.log 2>&1
# 簡寫
grep "Cat" file.log &> one.log