1 .創建shell腳本
第一步:使用文本編輯器來創建文本文件(后綴需要加 .sh)
?第一行必須包括shell聲明序列:#! #!/bin/bash ?添加注釋 注釋以#開頭 ?
第二步:運行腳本 ?給予執行權限,在命令行上指定腳本的絕對或相對路徑 ?直接運行解釋器,將腳本作為解釋器程序的參數運行
shell腳本的調試
bash -n +腳本 檢查腳本的語法錯誤
bash -x +腳本 調試執行腳本
腳本寫完后需要加上執行權限:chmod +x 腳本名
定義變量
變量的命名:1、不能使程序中的保留字:例如if, for
2、只能使用數字、字母及下劃線,且不能以數字開頭
3、見名知義
4、統一命名規則:駝峰命名法 (又分為大小駝峰:大駝峰;每個單詞的首字母都要大寫? 小駝峰;除了首個單詞首字母不需要大寫外其他單詞的首字母都要大寫)
變量的種類:
局部變量:生效范圍為當前shell進程;對當前shell之外的其它shell進程,包括 當前shell的子shell進程均無效(即使在子進程將變量更改后重新定義為全局變量,父進程的變量也不會更改)
環境(全局)變量:生效范圍為當前shell進程及其子進程 (將局部變量生成全局變量用export +變量名)
本地變量:生效范圍為當前shell進程中某代碼片斷,通常指函數
位置變量:$1, $2, …來表示,用于讓腳本在腳本代碼中調用通過命令行傳遞給它 的參數
特殊變量:$?, $0(腳本的名稱), $*(所有的參數), $@, $#(參數的個數),$$
變量的刪除 :unset + 加變量名
只讀和位置變量
? 只讀變量:只能聲明,但不能修改和刪除 ?
聲明只讀變量: readonly name declare -r name ? 查看只讀變量: readonly –p ?
位置變量:在腳本代碼中調用通過命令行傳遞給腳本的參數
$1, $2, …:對應第1、第2等參數,shift [n]換位置
$0: 命令本身 $*: 傳遞給腳本的所有參數,全部參數合為一個字符串
$@: 傳遞給腳本的所有參數,每個參數為獨立字符串
$#: 傳遞給腳本的參數的個數
$@ $* 只在被雙引號包起來的時候才會有差異
set — 清空所有位置變量
進程使用退出狀態來報告成功或失敗 0 代表成功,1-255代表失敗 (用echo $?來執行顯示)
bash自定義退出狀態碼 exit [n]:自定義退出狀態碼 注意:腳本中一旦遇到exit命令,腳本會立即終止;終止退出狀態取決于exit命 令后面的數字
算術運算
?bash中的算術運算:help let
+, -, *, /, %取模(取余), **(乘方)
實現算術運算:
(1) let var=算術表達式
(2) var=$[算術表達式]
(3) var=$((算術表達式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare –i var = 數值
(6) echo ‘算術表達式’ | bc ?
乘法符號有些場景中需要轉義,如* ?
bash有內建的隨機數生成器:$RANDOM(0-32767)
echo $[$RANDOM%50] :0-49之間隨機數
賦值
?增強型賦值:
+=, -=, *=, /=, %= ?
let varOPERvalue 例如:let count+=3
自加3后自賦值 ?
自增,自減:
let var+=1
let var++
let var-=1
let var–
與和或
& 并且 and
| 或者 or
0&0=0
0&1=0
1&0=0
1&1=1
0|0=0
0|1=1
1|0=1
1|1=1
短路與 &&
短路或 ||
0&&0=0 ? ? ?? 0||0=0
0&&1=0 ? ? ? ? 0||1=1
1&&0=0 ? ? ?? 1||0=1
1&&1=1 ? ? ? ?? 1||1=1
cmd1 && cmd2
如果cmd1為假,cmd2不需要執行,反之cmd1為真,需要cmd2執行
cmd1 || cmd2
如果cmd1為真,cmd2不需要執行,反之cmd1為假,需要cmd2執行
XOR 異或
0^1=1
0^0=0
1^0=1
1^1=0
10
11
01
a=100
b=110
c=010
100=a
test條件測試語句
? 長格式的例子: test “$A” = “$B” && echo “Strings are equal” test “$A”-eq “$B” && echo “Integers are equal” ?
簡寫格式的例子: [? “$A” = “$B”? ] && echo “Strings are equal” [ “$A” -eq “$B” ] && echo “Integers are equal
?數值測試:
-gt 是否大于 ? ? ? ? ?? ( [ $a -gt 12 ]既$a是否大于12)
-ge 是否大于等于
-eq 是否等于
-ne 是否不等于
-lt 是否小于
-le 是否小于等于
-v (可以查看變量是否被設置例如[? -v? a ]? && echo ” set “如果被設置則顯示set其中變量a不需要加$符號 )
一般一個[? ]就可以但在正則表達式中需要用[[ ? ]]其中括號與內容要用空格隔開
bash的字符串測試
字符串測試:
= 是否等于
> ascii碼是否大于ascii碼
< 是否小于
!= 是否不等于
=~ 左側字符串是否能夠被右側的PATTERN所匹配 注意: 此表達式一般用于[[ ]]中;擴展的正則表達式
-z “STRING“ 字符串是否為空,空為真,不空為假
-n “STRING“ 字符串是否不空,不空為真,空為假 ?
注意:用于字符串比較時的用到的操作數都應該使用引號
Bash的文件測試
?存在性測試
-a FILE:同-e -e FILE: 文件存在性測試,存在為真,否則為假 ?存在性及類別測試
-b FILE:是否存在且為塊設備文件
-c FILE:是否存在且為字符設備文件
-d FILE:是否存在且為目錄文件
-f FILE:是否存在且為普通文件
-h FILE 或 -L FILE:存在且為符號鏈接文件
-p FILE:是否存在且為命名管道文件
-S FILE:是否存在且為套接字文件
文件權限測試:
-r FILE:是否存在且可讀
-w FILE: 是否存在且可寫
-x FILE: 是否存在且可執行 ?
文件特殊權限測試:
-u FILE:是否存在且擁有suid權限
-g FILE:是否存在且擁有sgid權限
-k FILE:是否存在且擁有sticky權限
?使用read命令來接受輸入 (默認功能是對變量賦值 例如read name;之后輸入2 ;echo $name )
?使用read來把輸入值分配給一個或多個shell變量
-p 指定要顯示的提示
-s 靜默輸入,一般用于密碼
-n N 指定輸入的字符長度N
-d ‘字符’ 輸入結束符
-t N TIMEOUT為N秒 read 從標準輸入中讀取值,給每個單詞分配一個變量
所有剩余單詞都被分配給最后一個變量 read -p “Enter a filename: “ FILE
bash的配置文件
?按生效范圍劃分,存在兩類: ?
全局配置:(對所有用戶都有效)
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
個人配置:
~/.bash_profile
~/.bashrc
2.locate和find命令
區別:locate命令搜索快速占用cpu資源少(利用索引數據搜索的)模糊搜索,無法及時搜到最新的文件,需要手動更新索引數據庫(updatedb)主要用于變化不平凡的文件搜索。
;find命令搜索速度慢占用資源多(他是在全磁盤中逐個搜索)可以搜到最新的文件,可精確匹配文件。參數眾多可以自定義各種變量搜索你所需要的文件??赡苤凰阉饔脩艟邆渥x取和執行權限的目錄 。
find
查找條件
?指搜索層級 -maxdepth level 最大搜索目錄深度,指定目錄為第1級
-mindepth level 最小搜索目錄深度 ?根據文件名和inode查找:
(指定文件目錄為第三層 find /etc/ -maxdepth 3 -mindepth 3 -name f2)
-name “文件名稱”:支持使用glob *, ?, [], [^]
-iname “文件名稱”:不區分字母大小寫
-inum n 按inode號查找
-samefile name 相同inode號的文件
-links n 鏈接數為n的文件
-regex “PATTERN”:以PATTERN匹配整個文件路徑字符串,而不僅僅是文件名稱。
?根據屬主、屬組查找:
-user USERNAME:查找屬主為指定用戶(UID)的文件
-group GRPNAME: 查找屬組為指定組(GID)的文件
-uid UserID:查找屬主為指定的UID號的文件
-gid GroupID:查找屬組為指定的GID號的文件
-nouser:查找沒有屬主的文件
-nogroup:查找沒有屬組的文件
根據文件大小來查找:
-size [+|-]#UNIT 常用單位:k, M, G,c(byte)
#UNIT: (#-1, #] 如:6k 表示(5k,6k]
-#UNIT:[0,#-1] 如:-6k 表示[0,5k]
+#UNIT:(#,∞) 如:+6k 表示(6k,∞)
?根據時間戳: 以“天”為單位;
-atime [+|-]#,
#: [#,#+1)
+#: [#+1,∞]
-#: [0,#)
-mtime -ctime
以“分鐘”為單位:
-amin -mmin -cmin
?根據權限查找:
-perm [/|-]MODE MODE: 精確權限匹配(find /etc/ perm 666,精確匹配文件必須為666的權限)
/MODE:任何一類(u,g,o)對象的權限中只要能一位匹配即可,或關系,+ 從centos7開始淘汰
(或的關系 find -perm /666 既只要有一位6匹配即可)
-MODE:每一類對象都必須同時擁有指定權限,與關系 0 表示不關注
(大于的關系find -perm 333 ,匹配只要大于等于333的權限文件都行)
? find -perm 755 會匹配權限模式恰好是755的文件 ? 只要當任意人有寫權限時,find -perm +222就會匹配 ? 只有當每個人都有寫權限時,find -perm -222才會匹配 ? 只有當其它人(other)有寫權限時,find -perm -002才會匹配
處理動作
?-print:默認的處理動作,顯示至屏幕 ?
-ls:類似于對查找到的文件執行“ls -l”命令 ?
-delete:刪除查找到的文件 ?
-fls file:查找到的所有文件的長格式信息保存至指定文件中 ?
-ok COMMAND {} \; 對查找到的每個文件執行由COMMAND指定的命令,對于 每個文件執行命令之前,都會交互式要求用戶確認
find示例
?備份配置文件,添加.orig這個擴展名 find -name “*.conf” -exec cp {} {}.orig \; ?
提示刪除存在時間超過3天以上的joe的臨時文件 find /tmp -ctime +3 -user joe -ok rm {} \; ?
在主目錄中尋找可被其它用戶寫入的文件 find ~ -perm -002 -exec chmod o-w {} \; ?
查找/data下的權限為644,后綴為sh的普通文件,增加執行權限 find /data –type f -perm 644 -name “*.sh” –exec chmod 755 {} \; ?
查看/home的目錄 find /home –type d -ls
練習
?1、查找/var目錄下屬主為root,且屬組為mail的所有文件 (find ? /var ? /( ? -user? root? -a -group mail/))或者find /var -user root -group mail?
2、查找/var目錄下不屬于root、lp、gdm的所有文件 ?
find /var -not \( -user root -o -usr lp -o -usr gdm \)
3、查找/var目錄下最近一周內其內容修改過,同時屬主不為root,也不是 postfix的文件
?find /var -mtime -7 -not \( -user root -o -user postfix \)
4、查找當前系統上沒有屬主或屬組,且最近一個周內曾被訪問過的文件
?find / -atime -7 -nouser -o -nogroup?
5、查找/etc目錄下大于1M且類型為普通文件的所有文件
find /etc -size +1M -type f?
6、查找/etc目錄下所有用戶都沒有寫權限的文件
?find /etc -not -perm /222 -ls
7、查找/etc目錄下至少有一類用戶沒有執行權限的文件
?find /etc -not -perm /222
8、查找/etc/init.d目錄下,所有用戶都有執行權限,且其它用戶有寫權限的文件
find /etc/init.d -perm -111 -a -perm -002 或者find /etc/init.d -perm -113
壓縮解壓及歸檔工具
compress/uncompress
?compress [-dfvcVr] [-b maxbits] [file …] -d: 解壓縮,相當于uncompress -c: 結果輸出至標準輸出,不刪除原文件 -v: 顯示詳情 ?uncompress 解壓縮 ?zcat file.Z >file
gzip/gunzip
?gzip [OPTION]… FILE … -d: 解壓縮,相當于gunzip -c: 將壓縮或解壓縮的結果輸出至標準輸出 -#:1-9,指定壓縮比,值越大壓縮比越大 ?zcat:不顯式解壓縮的前提下查看文本文件內容
bzip2/bunzip2/bzcat
?bzip2 [OPTION]… FILE … -k: keep, 保留原文件 -d:解壓縮 -#:1-9,壓縮比,默認為9
xz/unxz/xzcat
?xz [OPTION]… FILE … -k: keep, 保留原文件 -d:解壓縮 -#:1-9,壓縮比,默認為6 ?xzcat: 不顯式解壓縮的前提下查看文本文件內容
zip/unzip
?打包壓縮 zip –r /testdir/sysconfig /etc/sysconfig/ ?解包解壓縮 unzip sysconfig.zip cat /var/log/messages | zip messages – unzip -p message > message
tar工具
? tar(Tape ARchive,磁帶歸檔的縮寫) ?
tar [OPTION]…
(1) 創建歸檔 tar -cpvf /PATH/TO/SOMEFILE.tar FILE…
(2) 追加文件至歸檔: 注:不支持對壓縮文件追加 tar -r -f /PATH/TO/SOMEFILE.tar FILE…
(3) 查看歸檔文件中的文件列表 tar -t -f /PATH/TO/SOMEFILE.tar
(4) 展開歸檔 tar -x -f /PATH/TO/SOMEFILE.tar tar -x -f /PATH/TO/SOMEFILE.tar -C /PATH/
(5) 結合壓縮工具實現:歸檔并壓縮 -j: bzip2 ;bz2, ? ? ? ? ? -z: gzip ;gz, ? ? ? ? -J: xz;xz
(實現既打包同時壓縮;tar? -zcvpf ? data.tar.gz ?? /data ? ?? 講的是將/data目錄下的文件先打包成。tar格式同時壓縮成.gz格式的文件 ? -z和gzip 匹配使用)
解壓 tar -xvf? data.tar.gz? -c /指定目錄 解壓是都使用-xvf就可以了 后面跟不同的文件格式及目錄路徑 默認當前路徑
sed工具
?用法: sed [option]… ‘script’ inputfile… ?
常用選項:
-n:不輸出模式空間內容到屏幕,即不自動打印
-e: 多點編輯 (可以操作多次 )例如sed -n -e ‘1~2p’ ?? -e? ‘2p’ ? /etc/passwd
-f:/PATH/SCRIPT_FILE: 從指定文件中讀取編輯腳本
-r: 支持使用擴展正則表達式
-i.bak: 備份文件并原處編輯 ?
script: ‘地址命令’
地址定界:
(1) 不給地址:對全文進行處理
(2) 單地址: #: 指定的行,$:最后一行 /pattern/:被此處模式所能夠匹配到的每一行(可定義//里的內容來搜索)例如/^s/搜以s開頭的行 ? /^e/,/^h/及搜素以e開頭以h結尾的行。
(3) 地址范圍: #,# #,+# /pat1/,/pat2/ #,/pat1/
(4) ~:步進 1~2 奇數行 2~2 偶數行 例如sed -n ‘1~2p’ /etc/passwd 打印奇數行? sed -n ‘2~2p’ /etc/passwd 打印偶數行
? 編輯命令:
d: 刪除模式空間匹配的行,并立即啟用下一輪循環
p:打印當前模式空間內容,追加到默認輸出之后
a [\]text:在指定行后面追加文本 支持使用\n實現多行追加
i [\]text:在行前面插入文本
c [\]text:替換行為單行或多行文本
w /path/somefile: 保存模式匹配的行至指定文件
!:模式空間中匹配行取反處理
sed -e ‘/^#NameVirtual/s/#//’ -e ‘/^#<VirtualHost/,/^#<\/VirtualHost/s/#//’ /etc/httpd/conf/httpd.conf? 此案例使用先搜索后替代并使用多點編輯 ,前面搜索的為單個定義的行,后面搜索的為自定義的行 /q/,/w/ 及q到w的行
s///:查找替換,支持使用其它分隔符,s@@@,s### ?替換標記:
g: 行內全局替換
p: 顯示替換成功的行
w /PATH/TO/SOMEFILE:將替換成功的行保存至文件中
sed ‘2p’ /etc/passwd
?sed –n ‘2p’ /etc/passwd ?
sed –n ‘1,4p’ /etc/passwd
?sed –n ‘/root/p’ /etc/passwd
?sed –n ‘2,/root/p’ /etc/passwd 從2行開始
?sed -n ‘/^$/=’ file 顯示空行行號
?sed –n –e ‘/^$/p’ –e ‘/^$/=’ file
?sed ‘/root/a\superman’ /etc/passwd行后
?sed ‘/root/i\superman’ /etc/passwd 行前
?sed ‘/root/c\superman’ /etc/passwd 代替行
sed ‘/^$/d’ file
?sed ‘1,10d’?? file ?nl /etc/passwd |
sed ‘2,5d’ ?nl /etc/passwd |
sed ‘2a tea’ ?
sed ‘s/test/mytest/g’ example ?
sed –n ‘s/root/&superman/p’ /etc/passwd 單詞后
?sed –n ‘s/root/superman&/p’ /etc/passwd 單詞前
?sed -e ‘s/dog/cat/’ -e ‘s/hi/lo/’ pets
?sed –i.bak? ‘s/dog/cat/g’ pets
高級編輯命令
?P:打印模式空間開端至\n內容,并追加到默認輸出之前 ?
h: 把模式空間中的內容覆蓋至保持空間中 ?
H:把模式空間中的內容追加至保持空間中 ?
g: 從保持空間取出數據覆蓋至模式空間 ?
G:從保持空間取出內容追加至模式空間 ?
x: 把模式空間中的內容與保持空間中的內容進行互換 ?
n: 讀取匹配到的行的下一行覆蓋至模式空間 ?
N:讀取匹配到的行的下一行追加至模式空間 ?
d: 刪除模式空間中的行 ?
D:如果模式空間包含換行符,則刪除直到第一個換行符的模式空間中的文本, 并不會讀取新的輸入行,而使用合成的模式空間重新啟動循環。如果模式空間 不包含換行符,則會像發出d命令那樣啟動正常的新循環
sed示例
?sed -n ‘n;p’ FILE ?
sed ‘1!G;h;$!d’ FILE
?sed ‘N;D‘ FILE ?
sed ‘$!N;$!D’ FILE
?sed ‘$!d’ FILE ?
sed ‘G’ FILE ?
sed ‘g’ FILE ?
sed ‘/^$/d;G’ FILE ?
sed ‘n;d’ FILE ?
sed -n ‘1!G;h;$p’ FILE
練習
?1、刪除centos7系統/etc/grub2.cfg文件中所有以空白開頭的行行首的空白字符
cat /etc/grub2.cfg | sed -r ‘s/(^[[:space:]])(.*)/\2/’
2、刪除/etc/fstab文件中所有以#開頭,后面至少跟一個空白字符的行的行首的# 和空白字符 ?
cat /etc/fstab | sed -r ‘s/(^#[[:space:]]+)(.*)/\2/’
3、在centos6系統/root/install.log每一行行首增加#號 ?
cat /root/install.log | sed ‘s/I/#I/’
4、在/etc/fstab文件中不以#開頭的行的行首增加#號 ?
cat /etc/fstab | sed ‘s/^[^#]/#/’
5、處理/etc/fstab路徑,使用sed命令取出其目錄名和基名 ?
echo “/etc/fstab” | sed -r ‘s@(.*\/)([^\/]+$)@\1@’取路徑
echo “/etc/fstab” | sed -r ‘s@(.*\/)([^\/]+$)@\2@’取基名
6、利用sed 取出ifconfig命令中本機的IPv4地址 ?
ifconfig | sed -n ‘2p’ | sed -r ‘s/(.*addr:)(.*)(Bcast.*)/\2/’ centos6上用
7、統計centos安裝光盤中Package目錄下的所有rpm文件的以.分隔倒數第二個 字段的重復次數
?ls /media/CentOS_6.9_Final/Packages/ | sed -r ‘s/(.*\.)(.*)(\.rpm)/\2/’ | sort | uniq -c | sort -nr
8、統計/etc/init.d/functions文件中每個單詞的出現次數,并排序(用grep和 sed兩種方法分別實現)
cat /etc/init.d/functions | grep -o “[[:alpha:]]\+” | sort | uniq -c | sort -rn
cat /etc/init.d/functions | sed -r ‘s/[^[:alpha:]]/\n/g’ | sed ‘/^$/d’ | sort | uniq -c | sort -rn
?9、將文本文件的n和n+1行合并為一行,n為奇數行
cat /etc/init.d/functions|tr -c ‘[:alpha:]’ ‘\n’|tr -s ‘\n’|sort|uniq -c|sort -nr
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/95597