# sed 是什麼? # sed : 字符流編輯器 Stream Editor; sed 擅長 替換、取行等 # sed 的功能與版本: 處理純文本文件、日誌、配置文件等 增長、刪除、修改、查詢 sed --version # 查看 sed 版本 # sed 語法格式: sed [選項] [sed指令] [輸入文件] sed -i.bak 's#oldboy#oldgirl#g' oldboy.txt # -i --- sed命令的參數 ;sed --- sed命令,一個指令 ;g --- 小尾巴, 修飾
模式空間: sed 從文件讀取一行文件後存入的緩衝區 (這個緩衝區是在內存中的)html
1. 查詢 2. 增長 3. 刪除 4. 替換 5. 拓展
# 建立測試環境: cat>person.txt<<EOF 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO EOF # cat>...<<EOF...EOF 表示建立文件 ; cat>>...<<EOF...EOF 表示向文件中追加內容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# # 1.1 顯示某一行 [root@NEO oldboy]# sed -n '3p' person.txt # -n 表示 取消默認輸出; '3p' 表示顯示第3行 103,Alex,COO # 1.2 顯示連續多行文本 # 顯示第2行到第4行的內容,包含第2行和第4行 [root@NEO oldboy]# sed -n '2,4p' person.txt # '2,4p' 表示顯示從第2行到第4行 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO # 1.3 顯示包含 oldboy 的行到 包含104的行 [root@NEO oldboy]# sed -n '/oldboy/p' person.txt # '/oldboy/p' ---> 表示 包含 oldboy 的行 ;此時 該行命令 至關於 grep 'oldboy',但 grep 不能過濾範圍 101,oldboy,CEO [root@NEO oldboy]# sed -n '/oldboy/,/104/p' person.txt # '/oldboy/,/104/p' ---> 包含 oldboy 的行 到 包含 104 的行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO [root@NEO oldboy]# sed -n '/oldboy/,/^104/p' person.txt # '/oldboy/,/^104/p' ---> 表示從包含 oldboy 的行到 以104開頭的行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO # 1.4 過濾多個字符串 # 默認狀況下,sed只支持基本正則表達式;sed 的 -r 參數,能夠支持 擴展正則表達式 (| 和 ()) # 顯示包含 oldboy 的行 或者 yy 的行 [root@NEO oldboy]# egrep 'oldboy|yy' person.txt 101,oldboy,CEO 104,yy,CFO [root@NEO oldboy]# sed -rn '/oldboy|yy/p' person.txt # -r '/oldboy|yy/p' ---> 表示 包含 oldboy 或者 yy 的行 101,oldboy,CEO 104,yy,CFO # sed 命令經過正則表達式進行過濾時,至關於 egrep # 1.5 查詢指定多行 [root@NEO oldboy]# sed -n '1p;3p' person.txt # '1p;3p' ---> 第1行 和 第3行; 多行之間用 逗號 分隔 101,oldboy,CEO 103,Alex,COO [root@NEO oldboy]# sed -n '1p;2,4p;5p' person.txt # , 和 ; 搭配使用 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed -n '/oldboy/p;3,5p' person.txt 101,oldboy,CEO 103,Alex,COO 104,yy,CFO 105,feixue,CIO
# 2.1 單行增長: # 在第3行後面增長一行內容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '3a 103.5,Lee,UFO' person.txt # 3a 表示在第3行的後面增長一行內容,3a 後面的空格沒有用,也能夠不寫 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 103.5,Lee,UFO 104,yy,CFO 105,feixue,CIO[root@NEO oldboy]# cat person.txt # sed '3a ' 命令並無真正修改文件內容,若是想要真正修改文件內容,能夠用 sed 的 -i 參數 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '3i 103.5,Lee,UFO' person.txt # 3i 表示在第3行的前面再增長一行內容;同理, 該命令也沒有真正修改文件內容,想要真正修改文件內容也是加上 -i 參數 101,oldboy,CEO 102,zhangyao,CTO 103.5,Lee,UFO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # 增長單選文本: a 參數 :追加 append,在指定行後添加一行或多行文本 i 參數 :插入 insert,在指定行前添加一行或多行文本 # 在最後一行插入: [root@NEO oldboy]# sed -n '$p' person.txt # 在 sed 命令中, $ 表示最後一行 105,feixue,CIO [root@NEO oldboy]# sed '$a 103.5,Lee,UFO' person.txt # 在最後一行插入一行內容 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO 103.5,Lee,UFO [root@NEO oldboy]# sed '$a new,new,new\nold,old,old' person.txt # 在最後一行增長多行內容,用 \n 分隔 (這種方法不經常使用;此命令已被 cat>>...<<EOF...EOF 替代,並且在最後一行的多行追加通常用 cat>> 方法) 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO new,new,new old,old,old
# 去除空行實戰:刪除最後一行 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '$d' person.txt # 刪除最後一行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO [root@NEO oldboy]# sed '1,3d' person.txt # 刪除第1行到第3行; d 表示 delete 104,yy,CFO 105,feixue,CIO # 企業案例:不顯示文件中空行 [root@NEO oldboy]# vim person.txt [root@NEO oldboy]# cat -nA person.txt # cat 的 -n 參數表示顯示 行號, -A 表示 顯示結尾的 $ 1 101,oldboy,CEO$ 2 102,zhangyao,CTO$ 3 $ 4 103,Alex,COO$ 5 $ 6 104,yy,CFO$ 7 $ 8 105,feixue,CIO$ [root@NEO oldboy]# grep -v '^$' person.txt # grep -v 表示 排除 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed '/^$/d' person.txt # sed 的 /^$/ 表示空行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # 另外一種方法: sed 的 ! 表示 取反; 在 p d 這些參數前面加 ! [root@NEO oldboy]# sed -n '/^$/p' person.txt # 顯示空行 [root@NEO oldboy]# sed -n '/^$/!p' person.txt # 排除空行 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# [root@NEO oldboy]# sed '$!d' person.txt # '$!d' : 不刪除最後一行 105,feixue,CIO
# 文本替換: sed -i 's#neo#NEO#g' oldboy.log # s 單獨使用 ---> 將每一行中 第一處匹配的字符串進行替換 # g (global:全局) ---> 每一行進行所有替換 --> sed 指令 s 的替換標誌之一(全局替換) # sed 的 -i 參數 ---> 用於修改文件; -i.ori ---> 自動備份;先備份源文件,而後修改文件的內容 [root@NEO oldboy]# cat person.txt 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed 's#o#AAAA#' person.txt 101,AAAAldboy,CEO 102,zhangyaAAAA,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed 's#o#AAAA#g' person.txt 101,AAAAldbAAAAy,CEO 102,zhangyaAAAA,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO
[root@NEO oldboy]# x=oldboy # oldboy 賦值給 x [root@NEO oldboy]# y=oldgirl # oldgirl 賦值給 y (中間不要有空格) [root@NEO oldboy]# sed 's#$x#$y#g' person.txt # '' ---> 所見即所得,因此 '' 中的內容沒有被解析 101,oldboy,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO [root@NEO oldboy]# sed "s#$x#$y#g" person.txt # "" 中的特殊符號($ $() `` !)會被解析 ; $x 表示 x變量 101,oldgirl,CEO 102,zhangyao,CTO 103,Alex,COO 104,yy,CFO 105,feixue,CIO # sed 的反向引用 :參考之前的
[root@NEO ~]# head -2 /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin [root@NEO ~]# awk -F ":" 'NR==2{print $1,$2}' /etc/passwd bin x # awk 語法格式: # awk 參數 '模式{動做}' 文件 ---> awk 參數 '條件(找誰){幹啥}' 文件
# 經過正則表達式做爲模式 # awk 使用正則表達式做爲模式 # 建立環境: mkdir -p /server/files/ cat >>/server/files/reg.txt<<EOF Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 EOF # 第1表表示姓,第2列表示名字,第3列表示ID,第4列表示捐款金額 [root@NEO server]# cat /server/files/reg.txt Zhang Dandan 41117397 :250:100:175 Zhang Xiaoyu 390320151 :155:90:201 Meng Feixue 80042789 :250:60:50 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 Wang Xiaoai 3515064655 :50:95:135 Zi Gege 1986787350 :250:168:200 Li Youjiu 918391635 :175:75:300 Lao Nanhai 918391635 :250:100:175 [root@NEO server]# # 2.1 找出包含 111 的行: [root@NEO files]# pwd /server/files [root@NEO files]# awk '/111/' reg.txt Zhang Dandan 41117397 :250:100:175 Wu Waiwai 70271111 :250:80:75 Liu Bingbing 41117483 :250:100:175 # 其它的正則表達式的用法在 awk 沒什麼變化,但 ^ 和 $ 在 awk 中不太同樣 ^ 表示 某一列中 以什麼開頭的字符串(以什麼開頭的列) : $3~/^oldboy/ 表示 第3列中 以 oldboy 開頭的字符串, ~ 可理解成 包含 $ 表示 某一列中 以什麼結尾的字符串(以什麼結尾的列) : $3~/oldboy$/ 同理 # 2.2 顯示Xiaoyu的姓名和ID號碼 [root@NEO files]# awk '/Xiaoyu/' reg.txt # 只有模式(由於沒有{});'/Xiaoyu/' 表示包含 Xiaoyu 的行,它至關於 '$0~/Xiaoyu/',即 把一整行看成一列, awk 的 $0 表示把一整行的內容放到了 $0 中(把一整行看成一列) Zhang Xiaoyu 390320151 :155:90:201 [root@NEO files]# awk '$0~/Xiaoyu/' reg.txt Zhang Xiaoyu 390320151 :155:90:201 [root@NEO files]# awk '/Xiaoyu/{print $1,$2,$3}' reg.txt # /Xiaoyu/ 表示包含 Xiaoyu 的行 Zhang Xiaoyu 390320151 [root@NEO files]# awk '$2~/Xiaoyu/{print $1,$2,$3}' reg.txt # $2~/Xiaoyu/ 表示 第2列(名字那一列)包含 Xiaoyu 的行 Zhang Xiaoyu 390320151 # 2.3 顯示全部以41開頭的ID號碼的人的全名和ID號碼 [root@NEO files]# awk '$3~/^41/{print $1,$2,$3}' reg.txt # $3~/^41/ ---> 第3列(ID那一列)以 41 開頭 Zhang Dandan 41117397 Liu Bingbing 41117483 # 2.4 顯示全部ID號碼最後一位數字是1或5的人的全名 [root@NEO files]# awk '$3~/[15]$/{print $1,$2}' reg.txt # $3~/[15]$/ 表示模式( {}外面的就是模式 ), {print $1,$2} 表示動做 Zhang Xiaoyu Wu Waiwai Wang Xiaoai Li Youjiu Lao Nanhai # 2.5 顯示Xiaoyu的捐款,每一個值都以 $ 開頭,如 $520$200$135 # 4. awk 裏面進行替換的方法 --- gsub 函數 : '{gsub(/要找的內容(支持正則)/,"替換成的內容",$列號)}' [root@NEO files]# awk '{gsub(/:/,"$",$4)}' reg.txt # 沒有輸出是由於 awk 沒有默認輸出 [root@NEO files]# awk '{gsub(/:/,"$",$4);print}' reg.txt # 再加上 ;print 就會有輸出 Zhang Dandan 41117397 $250$100$175 Zhang Xiaoyu 390320151 $155$90$201 Meng Feixue 80042789 $250$60$50 Wu Waiwai 70271111 $250$80$75 Liu Bingbing 41117483 $250$100$175 Wang Xiaoai 3515064655 $50$95$135 Zi Gege 1986787350 $250$168$200 Li Youjiu 918391635 $175$75$300 Lao Nanhai 918391635 $250$100$175 # 第4列的 : 替換成了 $ # gsub(/目標/,"替換爲何",第幾列) # gsub(/目標/,"替換爲何") === gsub(/目標/,"替換爲何",$0) ---> 整行替換 [root@NEO files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print}' reg.txt Zhang Xiaoyu 390320151 $155$90$201 [root@NEO files]# awk '$2~/Xiaoyu/{gsub(/:/,"$",$4);print $4}' reg.txt $155$90$201 [root@NEO files]# # gsub() 是awk 的一個函數
# 特殊模式: BEGIN 和 END BEGIN{} ---> BEGIN裏面的內容,會在 awk 讀取文件內容以前運行 # 通常用於測試、計算等 END{} ---> END裏面的內容,會在 awk 讀取文件的最後一行以後運行 (END很經常使用) # 用來顯示最終結果(前面一直在計算,最後END顯示結果) [root@NEO files]# awk 'BEGIN{print "this is beginning"}' # 只寫了個BEGIN ,後面就不用接文件了 this is beginning [root@NEO files]# awk 'BEGIN{print "this is beginning"} {print NR,$0}' reg.txt # {print NR,$0} ---> NR 表示 行號 this is beginning # BEGIN的內容 1 Zhang Dandan 41117397 :250:100:175 2 Zhang Xiaoyu 390320151 :155:90:201 3 Meng Feixue 80042789 :250:60:50 4 Wu Waiwai 70271111 :250:80:75 5 Liu Bingbing 41117483 :250:100:175 6 Wang Xiaoai 3515064655 :50:95:135 7 Zi Gege 1986787350 :250:168:200 8 Li Youjiu 918391635 :175:75:300 9 Lao Nanhai 918391635 :250:100:175 # 統計 /etc/services 文件裏面的空行數量 [root@NEO files]# awk '/^$/{print NR}' /etc/services # '/^$/{print NR}' 22 266 299 320 326 393 461 474 479 486 494 506 512 518 583 584 [root@NEO files]# awk '/^$/{i=i+1;print i}' /etc/services # i=i+1 表示 把 i+1 的結果賦值給 i ,每一個增長1,因此這個公式用來統計;i=i+1 也能夠簡寫成 i++ ; i=i+1 和 print 之間用 ; 分隔 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@NEO files]# # i=i+1 === i++ ---> 用來統計 [root@NEO files]# awk '/^$/{i=i+1}END{print i}' /etc/services # {i=i+1}END{print i} ---> i=i+1 是先計算,END{print i} 表示 文件讀取文件最後一行後 執行 {print i} 16 [root@NEO files]# awk '/^$/{i++}END{print i}' /etc/services # i++ 至關於 i=i+1 16
#awk數組-統計與計算 # awk 數組的組成: hotel[110]="張三" # hotel 表示 數組的名字(酒店名稱), 110 表示數組的元素名稱(房間號), 張三 表示 元素內容(房間內容) ; hotel[110] 組成了一個數組 [root@NEO files]# awk 'BEGIN{hotel[110]="NEO";hotel[114]="XO";print hotel[110],hotel[114]}' # 110]="NEO" ---> 建立數組;print hotel[110] ---> 把數組中的內容顯示出來 NEO XO # 處理如下文件內容,將域名取出並根據域名進行計數排序處理:(百度和sohu面試題) http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html [root@NEO files]# cat url.txt http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html [root@NEO files]# awk -F "[/.]+" '{print $2}' url.txt # 讓 $2 做爲數組的元素 www www post mp3 www post # h[$2] 表示 把 第2列(www post mp3)做爲元素名稱組成一個數組;一共有 3個元素 # h[$2]++ 表示 每一個元素名稱 遇到相同的元素名稱時 加1,遇到不一樣的元素名稱時不作處理 # h["www"] 表示 www 這個元素名稱中的 元素內容 [root@NEO files]# awk -F "[/.]+" '{h[$2]=h[$2]+1;print h["www"]}' url.txt 1 2 2 2 3 3 [root@NEO files]# # 顯示全部元素的內容 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{print h["www"],h["post"],h["mp3"]}' url.txt 3 2 1 # awk 本身提供的循環,可用於顯示數組裏面的內容: for(pol in h) ---> h是數組,pol 是h數組中的變量(數組的元素名稱;遍歷的也是數組的元素) [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol}' url.txt www mp3 post # 遍歷的是 數組的元素名稱 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print h[pol]}' url.txt # 把 元素名稱 放到 數組h中 3 1 2 [root@NEO files]# awk -F "[/.]+" '{h[$2]++}END{for(pol in h) print pol,h[pol]}' url.txt www 3 mp3 1 post 2
熟練使用 vim 編輯器
熟練 SSH終端
熟練掌握 Linux經常使用命令
熟練掌握Linux正則表達式及三劍客命令(grep sed awk)
# 1. 什麼是Shell ? # 命令解釋器; 你輸入的命令,誰來給你解釋/運行 # CentOS默認的 Shell 是 bash : echo $SHELL /etc/passwd .sh 結尾的文件 file 命令也能夠查看文件類型 [root@NEO ~]# echo $SHELL /bin/bash [root@NEO ~]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin /bin/dash /bin/tcsh /bin/csh [root@NEO ~]# file /etc/init.d/iptables /etc/init.d/iptables: POSIX shell script text executable # shell script ---> shell腳本 # 2. 什麼是Shell腳本? # 命令大禮包 --- 一個程序文件,包含若干行Linux命令語句 # 循環,條件語句 # 建立shell腳本: # 1. 統一腳本存放目錄 # 如: /server/scripts/ # 2. 推薦使用 vim 編輯器編程腳本 # 由於 vim 自帶顏色 # 3. 第一行指出由哪一個解釋器來執行腳本中的內容: #!/bin/bash ---> #! 稱爲幻數,能被內核識別 ---> 必須寫在第一行,若是不是第一行則爲腳本註釋行 ---> 雙能夠寫爲 #!/bin/sh # 4. 版權聲明 # 5. 寫一個簡單腳本(切換目錄顯示文件屬性)並運行 # 腳本目錄示例: [root@NEO ~]# [root@NEO ~]# ls -l /server/scripts/ total 8 -rw-r--r-- 1 root root 66 Apr 7 23:22 ip.sh -rw-r--r-- 1 root root 9 Apr 7 14:30 show_date.sh # 腳本註釋 & 版權聲明: [root@NEO ~]# vim /server/scripts/ip.sh [root@NEO ~]# cat /server/scripts/ip.sh #!/bin/bash #!/bin/bash 表示 這個腳本是用 /bin/bash 運行解釋的 # desc: show ip address # author: neo # time: 20190416 # version: v1.0 /sbin/ifconfig eth0 |awk -F "[ :]+" 'NR==2{print $4}' [root@NEO ~]# file /server/scripts/ip.sh /server/scripts/ip.sh: Bourne-Again shell script text executable [root@NEO ~]# /server/scripts/ip.sh # 正常運行腳本的方法:經過絕對路徑 -bash: /server/scripts/ip.sh: Permission denied # 在linux 中建立的文件默認的權限是 644 [root@NEO ~]# sh /server/scripts/ip.sh # 之後在執行腳本的時候都是運行 sh 命令 10.0.0.200
# 3.1 什麼是變量? # 用一個固定的字符串,替代更多更復雜的內容 # x=1 # devPath=/server/ # filelist=`ls` 或 $(ls) # 引用變量: $x 至關於 ${x} [root@NEO ~]# echo $PATH $LANG # 環境變量 /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin en_US.UTF-8 [root@NEO ~]# x=1 # 往變量中放值 ; x 是普通變量(局部變量) [root@NEO ~]# echo $x # 取出變量中的值 1 [root@NEO ~]# # 3.2 變量的分類: # 3.2.1 局部變量(普通變量): 只能在建立它們的Shell函數或Shell腳本中使用 定義變量: 變量名=value 變量名要求: 字母、數字、下劃線組成,必須以字母或下劃線開頭 規範的變量名寫法定義:見名知意 駝峯語法:首個單詞字母小寫,其他單詞首字母大寫 ---> oldAgeSex=1 把一個命令做爲變量 普通字符串定義測試 [root@NEO ~]# week=10 [root@NEO ~]# echo $weekday # 此時系統認爲 weekday 這個總體是個變量 [root@NEO ~]# echo ${week}day # $week 就至關於 ${week} 10day [root@NEO ~]# # 3.2.2 全局變量(環境變量): 大寫,在Linux中絕大地方均可以用 在建立他們的Shell及其派生出來的子Shell中使用 分類: 查看全局變量: env ---> 只顯示全局變量 bash內置的環境變量: Shell經過環境變量來肯定 登錄用戶名、命令路徑、終端類型、登錄日誌等 LANG PAHT SEHLL UID 等 自定義環境變量: 建議全部環境變量名均爲大寫 必須用 export 命令定義 取消變量: unset 永久生效 [root@NEO ~]# echo $LANG $PATH $PS1 en_US.UTF-8 /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin [\u@\h \W]\$ [root@NEO ~]# # 全局變量 和 局部變量 [root@NEO ~]# vim /server/scripts/show_date.sh [root@NEO ~]# cat /server/scripts/show_date.sh #!/bin/hash # desc: # author: # time: # version: echo $OLDBOY [root@NEO ~]# OLDBOY=10 # 此時的 OLDBOY 是一個普通變量,在 /server/scripts/show_date.sh 這個腳本中沒法使用 [root@NEO ~]# echo $OLDBOY 10 [root@NEO ~]# sh /server/scripts/show_date.sh # 輸出爲空,由於 OLDBOY 是個局部變量,在 這個腳本中沒法使用 [root@NEO ~]# # 讓普通變量變成全局問題的方法: export 命令; export 是臨時生效;取消全局問題的方法 : unset 命令, unset 不但能取消全局變量,也能取消局部變量 [root@NEO ~]# export OLDBOY # 讓 OLDBOY 這個普通變量 變成 全局變量 [root@NEO ~]# sh /server/scripts/show_date.sh 10 # 此時 OLDBOY 就能在 該腳本中使用了 [root@NEO ~]# [root@NEO ~]# env |grep OLDBOY OLDBOY=10 [root@NEO ~]# unset OLDBOY [root@NEO ~]# env |grep OLDBOY [root@NEO ~]# # 3.2.3 Shell 編程之環境變量相關的文件和目錄: 全局環境變量配置文件: /etc/profile ---> 修改環境變量的文件 /etc/bashrc /etc/profile.d/ ---> 用戶登錄到系統 會運行這個目錄下面的腳本 ;腳本要有執行權限 用戶本身的環境變量配置文件: ~/.bash_profile ~/.bashrc # 修改 /etc/profile.d/ 下的文件 ---> 用戶登錄到系統會自動運行 [root@NEO ~]# ls /etc/profile.d/ colorls.csh cvs.csh glib2.csh lang.csh less.csh vim.csh which2.sh colorls.sh cvs.sh glib2.sh lang.sh less.sh vim.sh [root@NEO ~]# vim /etc/profile.d/show.sh [root@NEO ~]# cat /etc/profile.d/show.sh #!/bin/bash # desc: show ip address of eth0 # author: neo # time: 20190417 # version: v1.0 ip a s eth0 [root@NEO ~]# ll /etc/profile.d/show.sh -rw-r--r-- 1 root root 104 Apr 17 02:00 /etc/profile.d/show.sh [root@NEO ~]# chmod +x /etc/profile.d/show.sh [root@NEO ~]# ll /etc/profile.d/show.sh -rwxr-xr-x 1 root root 104 Apr 17 02:00 /etc/profile.d/show.sh WARNING! The remote SSH server rejected X11 forwarding request. Last login: Tue Apr 16 20:48:25 2019 from 10.0.0.1 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:26:b5:57 brd ff:ff:ff:ff:ff:ff inet 10.0.0.200/24 brd 10.0.0.255 scope global eth0 inet6 fe80::20c:29ff:fe26:b557/64 scope link valid_lft forever preferred_lft forever [root@NEO ~]# # 本身寫的跳板機放到 /etc/profile.d/ 下面 # 特殊變量: # 位置變量: $0 (在腳本中) 獲取當前執行的shell腳本的文件名 若是執行腳本帶路徑那麼就包括腳本路徑 模擬系統腳本使用 $0 $n n 表示數字;$n 表示 第n個參數 $# 表示參數的個數 # 進程狀態變量 $? ---> 顯示上一個命令的執行結果;命令執行正確 ---> 結果爲0 , 命令執行錯誤 ---> 結果非0 ;軟件安裝後可用 $? 判斷是否安裝成功 # 位置變量: # 環境建立: [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: echo '$0:'$0 '$1:'$1 '$2:'$2 '$3:'$3 '$#:'$# # '$0:' 須要用單引號,雙引號的話就被解析了 [root@NEO scripts]# sh show_args.sh $0:show_args.sh $1: $2: $3: $#:0 # $0 表示腳本的名字; $n 在腳本中表示第n個參數 [root@NEO scripts]# sh show_args.sh arg1 arg2 arg3 arg4 arg5 arg6 # 腳本後面能夠跟參數 $0:show_args.sh $1:arg1 $2:arg2 $3:arg3 $#:6 # $# 表示參數的個數(腳本中一共有多少個參數) [root@NEO scripts]# ls /root/alex.oldboy.txt ls: cannot access /root/alex.oldboy.txt: No such file or directory [root@NEO scripts]# echo $? 2 # 執行錯誤 [root@NEO scripts]# ls /root/ alex.txt anaconda-ks.cfg data echotest.txt install.log.syslog oldboy-20171111.log [root@NEO scripts]# echo $? 0 # 執行正確 [root@NEO scripts]# # 變量賦值方法 --- read # 如何向變量中放內容? [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: x=1 y=2 echo $x $y [root@NEO scripts]# sh show_args.sh 1 2 # 若是 x y 是動態的參數,則利用下面的方法 [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: x=$1 # 改爲 $1 和 $2 y=$2 echo $x $y [root@NEO scripts]# sh show_args.sh 10 20 # 傳參10和20;10傳給$1 ,20傳給 $2 10 20 # read 可以從命令行中讀取內容放到變量中 (交互式的) [root@NEO scripts]# read -p "input x y:" x y input x y:10 20 [root@NEO scripts]# echo $x 10 [root@NEO scripts]# echo $y 20 [root@NEO scripts]# [root@NEO scripts]# vim show_args.sh [root@NEO scripts]# cat show_args.sh #!/bin/bash # desc: # author: neo # time: # version: # x=$1 # y=$2 read -p "input x y:" x y echo $x $y [root@NEO scripts]# sh show_args.sh input x y:30 40 30 40 [root@NEO scripts]#
條件表達式: 格式:[<測試表達式>] 先敲一對 [] ,而後退格輸入2個空格 [ ],最後再回退一個空格開始輸入,即 [] 兩端要各有一個空格,如: [ -f /etc/hosts ] 判斷文件: -f ---> 文件是否存在 -d ---> 目錄是否存在 0 存在,1 不存在 判斷整數: 等於 equal ---> -eq 不等於 not equal ---> -ne 大於 greater than ---> -gt 大於等於 greater euqal ---> -ge 小於 less than ---> -lt 小於等於 less euqal ---> -le 簡單案例 # Shell編程之測試表達式 --- 中括號 # [] 表示判斷或測試 [root@NEO scripts]# [ -f /root/alex.oldboy.txt ] # 判斷 /root/alex.oldboy.txt 這個文件是否存在 [root@NEO scripts]# echo $? 1 # 1 表示 [ -f /root/alex.oldboy.txt ] 查找的文件不存在, 0 表示存在 [root@NEO scripts]# [ -f /oldboy/oldboy.txt ] [root@NEO scripts]# echo $? 0 [root@NEO scripts]# [ -d /root ] # 判斷 /root 這個目錄是否存在; -d 判斷目錄是否存在 , -f 判斷文件是否存在 [root@NEO scripts]# echo $? 0 # 判斷整數: [root@NEO scripts]# [ 1 -eq 1 ] [root@NEO scripts]# echo $? 0 # 判斷整數的簡單案例:判斷命令行參數個數等於2 [root@NEO scripts]# sh ./args.sh [root@NEO scripts]# sh ./args.sh a b arg number is 2 [root@NEO scripts]# # 若是 /oldboy 目錄不存在則建立 [root@NEO ~]# [ -d /oldboy ] || mkdir -p /oldboy/ # 命令1 || 命令2 ---> || 表示 命令1不成立 則執行 命令2 # 若是 /root/oldboy.txt 存在則提示文件已經存在 [root@NEO ~]# [ -f /oldboy/oldboy.txt ] && echo file exists file exists # Shell編程之 if 判斷 # 單分支條件語句: # 語法: if [ 條件 ];then 命令 fi # [] 中括號兩端要有兩個空格 # 案例:輸入2個字,比較大小 # 語法: # if 單分支: [root@NEO scripts]# vim compare.sh [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 fi [root@NEO scripts]# sh compare.sh greater than [root@NEO scripts]# sh compare.sh 10 20 [root@NEO scripts]# sh compare.sh 20 10 20 greater than 10 [root@NEO scripts]# # if 雙分支: [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 else echo $num1 less equal $num2 fi [root@NEO scripts]# sh ./compare.sh 10 20 10 less equal 20 [root@NEO scripts]# sh ./compare.sh 20 10 20 greater than 10 [root@NEO scripts]# sh ./compare.sh 20 10 1 3 2 5 7 # 不足之處:後4個參數無用 20 greater than 10 [root@NEO scripts]# sh ./compare.sh 20 ./compare.sh: line 9: [: 20: unary operator expected 20 less equal [root@NEO scripts]# # 參數必須是2個 [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $# -ne 2 ];then echo "Useage:please input 2 numbers:num1 num2" exit # 退出程序 fi if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 else echo $num1 less equal $num2 fi [root@NEO scripts]# sh compare.sh 10 Useage:please input 2 numbers:num1 num2 [root@NEO scripts]# sh compare.sh 10 20 30 Useage:please input 2 numbers:num1 num2 [root@NEO scripts]# # if 多分支: [root@NEO scripts]# cat compare.sh #!/bin/bash # desc: # author: neo # time: 20190418 # version: 1.0 num1=$1 num2=$2 if [ $# -ne 2 ];then echo "Useage:please input 2 numbers:num1 num2" exit fi if [ $num1 -gt $num2 ];then echo $num1 greater than $num2 elif [ $num1 -lt $num2 ];then echo $num1 less equal $num2 else echo $num1 equal to $num2 fi [root@NEO scripts]# # shell 不太擅長小數
# for 循環語句: # 格式: for 變量名字 in 列表 do 命令 done [root@NEO scripts]# for num in 1 2 3 4 5 > do > echo "the $num number is:"$num > done the 1 number is:1 the 2 number is:2 the 3 number is:3 the 4 number is:4 the 5 number is:5 [root@NEO scripts]# # 優化linux開機啓動項目,只保留 crond,sshd,network,rsyslog,sysstat ,其餘的都關閉 # 思路: chkconfig 服務 off # 第一步:先排除上面的那幾個服務 [root@NEO scripts]# chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v # 第二步:取出全部的服務名 [root@NEO scripts]# chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v|awk '{print $1}' # for 循環遍歷關閉 [root@NEO scripts]# for service in `chkconfig |egrep "crond|sshd|network|rsyslog|sysstat" -v|awk '{print $1}'` > do > echo chkconfig $service off # echo 爲了測試 > done