3.1 vim
只記錄一些不太熟悉且強(qiáng)大的命令:
- 功能鍵[home]或者
0
:到行首艺栈; - 功能鍵[end]或者
$
:到行尾; - 數(shù)字+回車:往下走多少行檩禾;
- [ctrl] +
v
:矩形區(qū)塊選擇; -
u
:撤銷场躯; - [ctrl]+
r
:redo; -
.
:重復(fù)上個(gè)指令 -
y
是復(fù)制旅挤,d
是刪除踢关,有一些通用變種:-
yy
是一行,數(shù)字+yy
是幾行粘茄,y1G
是從頭到光標(biāo)位置签舞,yG
是到結(jié)尾,y0
是到行首柒瓣,y$
是到行尾儒搭。
-
-
:1,$s/word1/word2/gc
,從頭到尾替換word1為word2嘹朗,c
是可選的师妙,在替換前請求確認(rèn)。
-:w [filename]
:另存為屹培, 甚至還有:n1,n2 w [filename]
默穴。 -
:sp [filename]
:分屏打開另一個(gè)文件。[ctrl] +w+↑
用來切換窗口褪秀。 -
:set nu
:顯示行號蓄诽。 -
:! ls /usr
:暫時(shí)離開vim去執(zhí)行別的命令。
3.2 shell基礎(chǔ)
本節(jié)的shell都以bash為例說明媒吗。
3.2.1 一些普通命令
-
[ctrl]+u
:從當(dāng)前位置刪到開頭仑氛,+k
則是刪到結(jié)尾; -
[ctrl]+s
:暫停屏幕輸出闸英,+q
恢復(fù)屏幕輸出锯岖。這些都可以通過stty
命令來查看修改。 -
alias
可以給命令起別名甫何,對復(fù)雜且常用的命令很好用 -
history
是歷史命令出吹,不過條數(shù)有限。另外也建議不要給同一個(gè)用戶開多個(gè)連接辙喂,因?yàn)闅v史記錄會被覆蓋亂掉捶牢。 -
printf
可以在命令行上格式化打印數(shù)據(jù),和C語言很像巍耗。 - 差異比較:
-
diff file1 file2
可以查看兩個(gè)文件的差異秋麸,在行的級別上;還可以比較目錄炬太。- 通過
diff
灸蟆,我們可以制作補(bǔ)丁文件,diff -Naur old_file new_file > file.patch
- 然后通過
patch
命令亲族,可以將舊文件更新成新文件次乓。
- 通過
-
cmp
會找字節(jié)級別上的差異吓歇。
-
- 命令的查找路徑:
- 絕對或相對路徑:
./program
-
alias
中的命令 - shell 內(nèi)置命令,比如
cd
- 操作系統(tǒng)提供的腳本票腰,即
$PATH
的目錄中提供的腳本程序城看。
- 絕對或相對路徑:
- 多條命令的執(zhí)行:
-
;
是多條指令連續(xù)執(zhí)行; -
&&
是前一條成功了杏慰,后面一條執(zhí)行测柠;否則不執(zhí)行。 -
||
恰好反過來缘滥,前一條失敗了轰胁,后面一條執(zhí)行,否則不執(zhí)行朝扼。
-
3.2.2 變量和環(huán)境變量
-
env
觀察所有環(huán)境變量赃阀,set
觀察所有環(huán)境變量+自定義變量,echo
觀察一個(gè)變量擎颖。 - 讀取環(huán)境變量時(shí)榛斯,需要用
$
,但對其修改時(shí)則不用搂捧,修改時(shí)只需var=/home/user
即可驮俗。- 注意:為變量賦值時(shí),單引號里面的值全部解析為純文本允跑,也就是不能讀取其他變量王凑;但是雙引號里面是可以解析變量的。
- 變量是可以累加的聋丝,最經(jīng)典的
PATH=${PATH}:/usr/local/bin
索烹,不需要任何符號,直接把變量放上去就行了弱睦。 - 變量也可以從用戶輸入中讀取百姓,使用
read
命令,read -p "input sth." var
-
export
可以將自定義變量share給子進(jìn)程每篷,但也只有子進(jìn)程可以看到瓣戚。
- 變量類型可以定義為字符串(默認(rèn))端圈,整數(shù)焦读,數(shù)組。命令為
declare -i/a var
舱权。參數(shù)-x
可以將var
設(shè)為當(dāng)前shell的環(huán)境變量矗晃,如下條。 - 命令中如果需要其他命令的返回值宴倍,可以用
$(locate find)
括起來或者用``包裹起來张症。 - 像linux的命令提示符仓技,就是由環(huán)境變量來設(shè)置格式的;
- 上一條指令的執(zhí)行結(jié)果俗他,會存在一個(gè)系統(tǒng)變量
$?
脖捻,一般成功則為0。 -
變量判斷檢測:
- 變量還可以做刪除一部分和替換一部分兆衅,也可以檢測某個(gè)變量是否存在或是否為空地沮。
- 在用戶登錄shell的時(shí)候,shell會自己讀入一組環(huán)境變量羡亩,讀入的文件有兩個(gè):
-
/etc/profile
:整個(gè)系統(tǒng)的環(huán)境變量摩疑,在這個(gè)腳本中,還會額外讀入并執(zhí)行:
-
/etc/profile.d/*.sh
:一些基本環(huán)境和alias -
/etc/locale.conf
:語系設(shè)置 -
/usr/share/bash-completion-completions
:自動補(bǔ)齊規(guī)則
-
~/.bash_profile
:用戶的環(huán)境變量畏铆,如果沒有的話就依次找~/.bash_login
或者~/.profile
。會額外讀入:
-
~/.bashrc
:一些個(gè)人設(shè)置辞居,沒登錄的時(shí)候也會激活楷怒。
-
-
source
或者.
命令可以主動激活一個(gè)配置文件 -
~/.bash_logout
:注銷shell時(shí)的操作。
3.2.3 高級命令
3.2.3.1 通配符與正則表達(dá)式
shell的命令中有四種通配符可以用:
-
*
:任意多個(gè)任意字符 -
?
:一個(gè)任意字符 -
[abcd]
:方括號中的一個(gè)字符速侈。類似正則表達(dá)式率寡,[0-9]
,[^a-c]
的用法也支持倚搬。
通配符由shell負(fù)責(zé)解析喳瓣,正則表達(dá)式則由命令本身負(fù)責(zé)解析。能支持正則表達(dá)式的命令則不再使用通配符規(guī)則翅睛,比如grep
钱反,sed
,awk
等眨层。
-
^
代表行首庙楚,$
代表行尾; -
.
和通配符中的?
含義一致趴樱; -
*
用來表示前一個(gè)字符零個(gè)或任意多個(gè)馒闷; -
\{n\}
表示n個(gè)前一個(gè)字符,\{n,m\}
表示[n,m]個(gè)前一個(gè)字符叁征,\{n,\}
表示大于等于n個(gè)前一個(gè)字符纳账。 - 方括號和通配符規(guī)則一致。
- 【擴(kuò)展版】
+
表示一個(gè)或多個(gè)前一個(gè)字符捺疼,?
表示0個(gè)或1個(gè)前一個(gè)字符疏虫。 - 【擴(kuò)展版】
|
表示或。 - 【擴(kuò)展版】
()
可以把部分正則表達(dá)式括號成一個(gè)群組,比如:-
g(oo|la)d
表示兩個(gè)單詞之一卧秘,A(xyz)+c
表示中間一個(gè)或多個(gè)xyz呢袱。
-
一些常用的正則表達(dá)式搭配:
-
.*
代表0個(gè)或任意多個(gè)任意字符; -
^$
:空白行
還有一些宏可以用在正則表達(dá)式里:
-
[:space:]
表示任何空白符翅敌,[:blank:]
表示空格和TAB -
[:lower:],[:upper:]
表示小寫/大寫英文字母羞福,[:alpha:]
代表所有英文字母 -
[:digit:]
代表所有數(shù)字,[:alnum:]
代表字母和數(shù)字
3.2.3.2 數(shù)據(jù)流重定向
命令執(zhí)行(可能)有三條數(shù)據(jù)流蚯涮,輸入數(shù)據(jù)流stdin坯临,標(biāo)準(zhǔn)輸出流stdout,標(biāo)準(zhǔn)錯(cuò)誤輸出流stderr恋昼,分別對應(yīng)代碼0,1,2看靠。數(shù)據(jù)流重定向是將數(shù)據(jù)的末端從屏幕變成文件。
-
>
:將標(biāo)準(zhǔn)輸出流輸出到文件中(覆蓋寫)液肌,>>
則是追加寫挟炬; -
2>, 2>>
是寫標(biāo)準(zhǔn)錯(cuò)誤流; -
2>&1 >, 2>&1 >>
是同時(shí)把輸出流和錯(cuò)誤列寫出來嗦哆; - 如果想丟棄這些輸出谤祖,可以重定向到
/dev/null
這個(gè)黑洞中去; -
<
是從文件中獲取輸入(而非命令行)老速,<<
是指定用戶鍵盤輸入的結(jié)束字符串(沒啥用)粥喜。 -
tee
:轉(zhuǎn)存命令,可以在多個(gè)管道命令傳遞數(shù)據(jù)之間額外保存中間結(jié)果到文件中橘券,參數(shù)-a
表示追加寫额湘。
3.2.3.3 管道命令
管道命令|
是將前一個(gè)命令的標(biāo)準(zhǔn)輸出作為后一個(gè)命令的標(biāo)準(zhǔn)輸入,這要求后一個(gè)命令必須能接受標(biāo)準(zhǔn)輸入旁舰,即是管道命令锋华。
-
grep
選行:last | grep 'root'
:將輸入中帶有pattern的行留下來,pattern支持正則表達(dá)式箭窜。參數(shù)-c
可以計(jì)數(shù)毯焕,-i
忽略大小寫,-v
反向選擇磺樱,-n
顯示行號纳猫,-A 3
顯示后幾行,-B 4
顯示前幾行竹捉。-
grep
有一個(gè)重要功能就是搜索文件中出現(xiàn)了什么關(guān)鍵字芜辕,比如grep 'key' ./*
,grep 'key' $(find . -type f)
,find . -type f | xargs -n 10 grep 'key'
-
-
cut
選列:echo $PATH | cut -d ":" -f 5,7
:將輸入的每一行,按照-d
后面的字符split活孩,然后取出第-f
個(gè)元素物遇。有一個(gè)參數(shù)-c
可以直接選擇字符的索引區(qū)間,比如export | cut -c 10-20
-
sort
排序:默認(rèn)按照字典序排序各行憾儒。參數(shù)-f
忽略大小寫询兴,-b
忽略前導(dǎo)空格,-r
反向排序起趾,-n
數(shù)值排序诗舰。-
less data.txt | sort -t ":" -k 3-5 -n
,用:
split训裆,按照第3-5列數(shù)值排序眶根。
-
-
uniq
去重:-i
忽略大小寫,-c
對每個(gè)元素進(jìn)行計(jì)數(shù)边琉。 -
tr
,join
等命令可以對數(shù)據(jù)做刪除/替換属百,兩組數(shù)據(jù)的join,笛卡爾積join等变姨,不詳細(xì)展開族扰。 -
wc
計(jì)數(shù):-l
統(tǒng)計(jì)行數(shù),-w
統(tǒng)計(jì)英文字母數(shù)定欧,-m
統(tǒng)計(jì)字符數(shù)渔呵。 -
split
劃分:-b
參數(shù)確定分割后的最大文件大小,-l
確定最大行數(shù)砍鸠。-
split -l 10 file new_files
:由于這里需要一個(gè)文件參數(shù)扩氢,如果在管道中就用-
來代替文件名代表從標(biāo)準(zhǔn)輸入中獲得,輸出的文件也可以用-
來代替代表標(biāo)準(zhǔn)輸出流爷辱。
-
-
xargs
將標(biāo)準(zhǔn)輸入流變成參數(shù):很多常用命令并非管道命令录豺,比如ls
,我們可以通過...|xargs ls
把標(biāo)準(zhǔn)輸入流變成參數(shù)傳給ls
命令饭弓。- 有些命令只能接受一個(gè)參數(shù)巩检,則可以用
...|xargs -n 1 ls
表示每次只傳遞一個(gè)參數(shù);另外-p
表示每次執(zhí)行都詢問示启,-e
可以設(shè)置最后一個(gè)參數(shù)是什么樣的兢哭。
- 有些命令只能接受一個(gè)參數(shù)巩检,則可以用
-
sed
:強(qiáng)大的數(shù)據(jù)操作工具。- 刪除:
...|sed '2,5d'
表示刪除【2,5】行夫嗓;...|sed '2,$d'
表示刪到結(jié)尾迟螺。 - 新增:
...|sed '2a new line'
表示在第二行下面新插入一行,文字為new line舍咖;通過\+回車
還可以直接插入多行矩父; - 替換:
...|sed '2,5c repleaced text'
,把[2,5]行替換成了一行replaced text排霉; - 打忧现辍:
...|sed -n '2,5p'
,很簡答,只打印[2,5]行球订,注意參數(shù)-n
表示只顯示操作的部分后裸; - 行內(nèi)替換:
...|grep 'sth'| sed 's/old word'/new word/g
,注意old word可以是一個(gè)正則表達(dá)式冒滩。 - 參數(shù)
-i
可以直接修改文件中的數(shù)據(jù)微驶。 - 參數(shù)
-e
,如果需要多個(gè)連續(xù)操作开睡,每個(gè)操作前面都需要加-e
- 刪除:
-
awk
: 表格式數(shù)據(jù)處理工具因苹。以換行符定義行,以空格或[tab]分割列(可以設(shè)置分割符)篇恒。awk會迭代處理每一行扶檐,$1
代表第一列,依次類推胁艰,然后判斷條件蘸秘,滿足則執(zhí)行操作。$0
最特殊蝗茁,表示一整行醋虏。
基本語法是awk '條件1{操作1} 條件2{操作2}'
-
... | awk '{print $1 "\t" $3}'
無條件,打印第一列和第三列的數(shù)據(jù)哮翘;
-
awk命令還藏了兩個(gè)變量颈嚼,NR
表示現(xiàn)在處理的是第幾行,NF
表示該行共有幾列饭寺。
... | awk '{print "cur line:" NR ", total columns: " NF}'
設(shè)置分隔符是另一個(gè)變量FS
-
... | awk 'BEGIN {FS=":"} $3<10{print $3}'
:第一個(gè)操作設(shè)置分隔符為:
阻课,隨后若第三列<10,則打印第三列艰匙。BEGIN表示從第一行的分隔符就是:
限煞,否則從第二行開始。
在awk的操作中员凝,即{}中署驻,可以有多條命令,用;
或者回車可以分隔健霹;甚至還可以定義變量旺上,且無需加上$
讀取變量;再甚至可以有條件邏輯和循環(huán)邏輯糖埋,非常強(qiáng)大
3.2.4 ulimit
-
ulimit
可以對各個(gè)用戶對系統(tǒng)的資源使用作出限制宣吱,比如:-
-d
是對一個(gè)進(jìn)程的內(nèi)存大小的限制(不僅僅是二進(jìn)制文件的數(shù)據(jù)段,也包括動態(tài)申請的堆)瞳别。 -
-l
最大鎖住的內(nèi)存征候,即釘死在內(nèi)存里杭攻,不允許交換的內(nèi)存數(shù)據(jù)。 - 【這個(gè)指令很強(qiáng)大疤坝,其他限制將繼續(xù)研究補(bǔ)充】
-
3.3 shell腳本
shell腳本就是一系列shell命令寫到文件里兆解,從上到下依次執(zhí)行而已。
規(guī)則是碰到回車就執(zhí)行當(dāng)前行命令卒煞,除非是用\+回車
換行。
基本規(guī)則:
- 第一行必須有
#!/bin/bash
用來指明這個(gè)腳本在哪個(gè)shell中執(zhí)行叼架,=畔裕。注意這不是注釋,沒有這一行系統(tǒng)不知道用哪個(gè)shell來執(zhí)行這個(gè)腳本乖订。 - 可以用
exit + 數(shù)字
來結(jié)束這個(gè)腳本扮饶。
執(zhí)行方式:
- 一種是直接執(zhí)行,用絕對/相對路徑執(zhí)行乍构,或者放到
$PATH
里面甜无,或者用sh
或bash
顯示執(zhí)行,其實(shí)都會啟用一個(gè)子進(jìn)程哥遮,在子進(jìn)程中執(zhí)行岂丘,執(zhí)行結(jié)束后,定義的變量也就丟棄了眠饮; - 另一種是用
source
來執(zhí)行奥帘,這樣是直接在父進(jìn)程中執(zhí)行,定義的變量也會得到保留仪召。 - 參數(shù)
-x
會打印執(zhí)行過的每一條命令寨蹋,可以用于調(diào)試。
腳本的參數(shù):腳本也可以擁有參數(shù)扔茅,在腳本中以特殊方式讀取
-
$1
代表第一個(gè)參數(shù)已旧,后續(xù)的依次類推; -
$0
代表腳本路徑召娜; -
$@
代表全部參數(shù)的一個(gè)變量
條件邏輯:
if [some condition] && [other condition]; then
sth
elif [conditon1] || [condition2]; then
sth
else [condition 3]
sth
fi
選擇邏輯:
case $var in
"one")
sth
;;
"two")
sth
;;
*)
echo "Usage: ./$0 one or two"
;;
esac
循環(huán)邏輯:
while [condition]
do
sth
done
until [condition]
do
sth
done
for var in one two three
do
sth
done
for var in $(ls .), for var in {1..100}, for var in $(seq 1 100)
for (( i=1; i<=${th}; i=i+1 ))
do
sth
done
shell內(nèi)的函數(shù):沒有返回值运褪,但是可以像命令那樣傳遞些參數(shù)進(jìn)來,里面仍然會有$1
,$2
,$0
是函數(shù)名玖瘸,但與整個(gè)腳本的不同吐句,只看調(diào)用的時(shí)候提供的參數(shù)。
function fname(){
echo "$1"
}
fname hello