Linux shell 三十六計

本文修改自《DevOps三十六計》中的Linux shell三十六計篇,原文作者阿銘,著有《跟阿銘學Linux》一書。

特殊命令

第一計

date可以格式化輸出時間,定義文件名的前綴或者後綴。如:

[root@VM_0_9_centos logs]# ls
server.2018-07-02.log  server.2018-07-12.log  server.2018-08-01.log  server.2018-08-02.log
[root@VM_0_9_centos logs]# date
Sat Aug  4 16:24:57 CST 2018
[root@VM_0_9_centos logs]# date -d '2 days ago' +%Y-%m-%d
2018-08-02
[root@VM_0_9_centos logs]# date +%Y-%m-%d
2018-08-04
[root@VM_0_9_centos logs]# rm *`date -d '2 days ago' +%Y-%m-%d`.log
rm: remove regular empty file ‘server.2018-08-02.log’? y
[root@VM_0_9_centos logs]# ls
server.2018-07-02.log  server.2018-07-12.log  server.2018-08-01.log
[root@VM_0_9_centos logs]#
#筆者經常用這個命令匹配日誌文件,然後放到crontab定時任務中,定時刪除一定時間前的無用日誌。
#不過,習慣上的`date +"%Y%m%d_%H:%M"` 和 $(date +"%Y%m%d_%H:%M")在crontab下不起作用,需採用如下形式 `date +"\%Y\%m\%d_\%H:\%M"` 和 $(date +"\%Y\%m\%d_\%H:\%M")

第二計

read -p可以實現用戶交互。

第三計

exec 1>/tmp/1.log 2>/tmp/error.log可以定義正確輸出和錯誤輸出。

第四計

mkpasswd可生成隨機字符串。

第五計

test可用於判定某條件是否成立,作爲邏輯判斷條件。

第六計

sleep可定義休眠時間,用於循環腳本中。

第七計

true和while可實現死循環,例如”while true”,它等同於”whiel:”。

第八計

在循環體裏面巧用break或continue,可控制循環體結束或者繼續。

第九計

echo -e識別換行符”\n”,echo -n忽略換行符。

第十計

嵌入文檔(Here Documents)將腳本中自定義文本內容作爲指定命令的輸入,典型用法:cat << EOF。

正則三劍客

第十一計

正則表達式中特殊符號含義要搞清楚。”.”表示任意字符,”*”表示它前面的字符有0個或多個,”+”表示它前面的字符有1個或多個,”?”表示它前面的字符有0個或1個,”.*”表示任意個任意字符。

第十二計

grep的選項”–color”,將匹配的關鍵字顯示爲紅色,方便定位。

第十三計

grep的”-E”選項支持擴展正則(表達式中含有”+” “?” “{}” “()” “|”等符號)匹配,如,grep -E ‘aaa|bbb’ filename,將匹配包含aaa或bbb的行。

第十四計

grep的”-r”選項實現遍歷目錄下所有文件。

第十五計

sed的”-i”選項直接修改文件內容。

第十六計

sed的”-r”選項支持擴展正則匹配,類似grep的”-E”選項。

第十七計

sed可以調換一個字符串裏不同字段的位置,例如調換第一個單詞和最後一個單詞的位置。

第十八計

awk的”-F”選項指定的分隔符可以是一個正則表達式,如awk -F ‘(:|#)’,分隔符可以是”:”或”#”。

第十九計

awk調用shell的變量,需要做一個特殊處理:a=1;awk -v b=$a’{print b}’。

第二十計

awk可以進行數學計算,並且可以結合循環實現計算某一段的綜合,如,awk -F ‘:’ ‘{sum += $3} END {print sum}’ /etc/passwd。

shell特殊符號

第二十一計

特殊符號”||”用在兩條命令中間,表示左邊的命令執行不成功時纔會執行其右邊的命令。

第二十二計

特殊符號”$”通常用來表示一個變量,如,a=1;echo $a。在shell中自身也有諸多自帶變量,比如,”$1”爲第一個參數,”$2”爲第二個參數,依次類推。”$#”表示參數個數。”$”符號的用法還有很多,比如檢查一條命令是否執行成功,根據返回值”$?”的值來判定。在正則表達式中,”$”表示結尾。

第二十三計

特殊符號”&&”也是在兩條命令中間使用,但它和”||”含義正好相反:當其左邊命令執行成功時纔會執行其右邊的命令。

第二十四計

反引號”`”(反引號在鍵盤左上角的波浪號鍵上)會將命令結果賦值給變量,方便調用。如:

[root@VM_0_9_centos ~]# ls
abc.txt  ac.txt  anaconda-ks.cfg  a.txt  b.txt  test
[root@VM_0_9_centos ~]# result=`ls *.txt`
[root@VM_0_9_centos ~]# echo $result
abc.txt ac.txt a.txt b.txt
[root@VM_0_9_centos ~]#

第二十五計

管道符號”|”會將其左邊命令的輸出內容作爲右邊命令的輸入內容。

第二十六計

通配符號”*”和正則表達式中的”*”含義不同,在shell裏面它表示通配,如ls *.txt會把所有.txt爲後綴的文件全部列出來。

第二十七計

轉義符號”\”會將特殊符號變爲普通字符。如ls *.txt會把所有.txt文件列出來,但如果使用ls \*.txt則只會把*.txt列出來,這裏的”*.txt”就是文件的名字。

第二十八計

註釋符號”#”後面的字符不再被shell解釋。爲了讓shell腳本更容易被人讀懂,應該加一些說明文字,這些文字的行首要加上”#”。

第二十九計

特殊符號”?”在shell中代表任何一個字符。比如ls ?.txt只把1.txt、2.txt、a.txt等列出來,而不會列出12.txt、aaa.txt。如:

[root@VM_0_9_centos ~]# ls
abc.txt  ac.txt  anaconda-ks.cfg  a.txt  b.txt  test
[root@VM_0_9_centos ~]# ls a?.txt
ac.txt

shell技巧

第三十計

test -n “$a”可以判斷變量a是否不爲空,test -z “$a”可以判斷變量a是否爲空,兩者正好相對。如:

[root@VM_0_9_centos ~]# a=`test -n "$b"`
[root@VM_0_9_centos ~]# echo $?
1
#上一行返回false,說明test -n "$b"的結果是false,即變量b是空,因爲我們之前沒定義這個變量
[root@VM_0_9_centos ~]# b=123
[root@VM_0_9_centos ~]# a=`test -n "$b"`
[root@VM_0_9_centos ~]# echo $?
0
#由於定義了b=123,這次返回的就是true

第三十一計

可以把一條命令作爲if的判斷條件,在shell腳本里很多情況下需要先判斷一條命令是否執行成功,判斷依據是根據命令執行後$?返回值是否是0。

第三十二計

如果在腳本中要處理的文本內容比較多,可以先存儲到一個臨時文件裏,這樣比存儲到變量裏更加方便,有時甚至是必要的,比如要處理超大文件時,全放變量裏就等於放在了內存裏。

第三十三計

調試腳本用-x,可以看到每一步運行過程,從而精準定位問題點。

第三十四計

crontab最小時間單元爲分鐘,while死循環結合sleep可以實現秒級的計劃任務。

第三十五計

虛擬終端screen非常實用,雖然不能在shell腳本里面用,但是在調試腳本或者運行常駐腳本時,使用虛擬終端是非常方便的。

第三十六計

expect腳本可以實現自動執行交互式的命令,例如遠程登錄一臺Linux服務器,並執行若干條命令,執行完後再退出。結合shell的for循環,可以實現批量操作。

其實筆者還有一些經常使用的命令推薦:


  • lsof

lsof -i:port命令可以查看端口是否被佔用,如:
[root@VM_0_9_centos ~]# lsof -i:8081
COMMAND   PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    26271 root  116u  IPv4 87571136      0t0  TCP *:tproxy (LISTEN)
[root@VM_0_9_centos ~]# lsof -i:8080
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    27382 root   49u  IPv4 281971      0t0  TCP *:webcache (LISTEN)
[root@VM_0_9_centos ~]# lsof -i:8082
[root@VM_0_9_centos ~]#
#可見,8080和8081都被佔用了,8082沒有被佔用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章