1. 程式人生 > >Shell程式設計及Bash

Shell程式設計及Bash

為什麼學習shell程式設計?

對於一個合格的系統管理員來說,學習和掌握Shell程式設計是非常重要的。通過程式設計,可以在很大程度上簡化日常的維護工作,使得管理員從簡單的重複勞動中解脫出來。
Shell程式的特點:
1、簡單易學。
2、解釋性語言,不需要編譯即可執行。


shell 特性

什麼是shell???

Shell又稱命令直譯器,它能識別使用者輸入的各種命令,並傳遞給作業系統。它的作用類似於Windows作業系統中的命令列,但是,Shell的功能遠比命令列強大的多。在UNIX或者localhost中,Shell既是使用者互動的介面,也是控制系統的指令碼語言。
在這裡插入圖片描述

shell種類

Bourne Shell:標識為sh,該Shell由Steve Bourne在貝爾實驗室時編寫。在許多Unix系統中,該Shell是root使用者的預設的Shell。
Bourne-Again Shell:標識為bash,該Shell由Brian Fox在1987年編寫,是絕大多數linux發行版的預設的Shell。
Korn Shell:標識為ksh,該Shell由貝爾實驗室的David Korn在二十世紀八十年代早期編寫。它完全向上相容 Bourne Shell 幷包含了C Shell 的很多特性。
C Shell:標識為csh,該Shell由Bill Joy在BSD系統上開發。由 於其語法類似於C語言,因此稱為C Shell。

什麼是shell指令碼?

當命令或程式語句不在命令列下執行,而是通過一個程式檔案來執行,該程式檔案即指令碼。

Shell指令碼執行

方法一:切換到shell指令碼所在的目錄(此時,稱為工作目錄)執行shell指令碼
方法二:以絕對路徑的方式去執行bash shell指令碼:
方法三:直接使用bash 或sh 來執行bash shell指令碼:
方法四:在當前的shell環境中執行bash shell指令碼:source或.
區別: 1、方法三:可以在指令碼中不指定直譯器,指令碼可以沒有執行許可權
2、方法一和方法二指令碼需要有執行許可權,./script_name.sh 或 /path/script_name.sh
3、方法四:當前shell執行,方法1-3開啟子shell

shell指令碼註釋

通過在程式碼中增加註釋可以提高程式的可讀性。傳統的Shell只支 持單行註釋,其表示方法是一個井號“#”,從該符號開始一直到行尾都屬於註釋的內容。
多行如何註釋?
使用者還可以通過其他的一些變通的方法來實現多行註釋,其中,最簡單的方法就是使用冒號“:”配合here document,語法如下:
:<<BLOCK
註釋內容
BLOCK

shell指令碼規範

開頭指定指令碼直譯器
#!/bin/sh或#!/bin/bash
其他行#表示註釋
名稱見名知義 backup_mysql.sh,以sh結尾
#Date: 建立日期
#Author: 作者
#Mail: 聯絡方式
#Function: 功能
#Version: 版本

Shell中會使用的一些查詢命令

Vi及Vim解析

Vi及Vim用法及命令

Grep及基本正則表示式

正則表示式就是為了處理大量的文字|字串而定義的一套規則和方法
對於系統管理員來講,正則表示式貫穿在我們的日常運維工作中,無論是查詢某個文件,抑或查詢某個日誌檔案分析其內容,都會用到正則表示式

Linux中的正則表示式,常應用正則表示式的命令是grep(egrep),sed,awk。Linux下三劍客!
正則表示式分為兩種:

  • 基本正則表示式(BRE,basic regular expression)
  • 擴充套件正則表示式(ERE,extended regular expression)
引數 作用
–color 匹配到的字串顯示顏色
-i 忽略字元大小寫
-o 僅顯示匹配的字串
-v 反向選取, 即顯示不匹配的行
-E 使用擴充套件正則表示式
-n 顯示行號
-w 匹配指定的字串
元資料 意義和範例
^word 搜尋word開頭的行
搜尋以#開頭的行,grep -n ‘^#’ file
word$ 搜尋word結尾的行
搜尋以.結尾的行,grep -n ‘.$’ file
. 匹配任意一個字元
匹配e和e之間有任意一個字元,grep -n ‘e.e’ file
\ 轉義字元
* 前面的一個字元重複0到多次
匹配gle,gogle,google,gooogle等,grep -n ‘go*gle’ file
[list] 匹配一系列字元中的一個
[n1-n2] 匹配一個字元範圍中的一個字元
匹配數字字元,grep -n ‘[0-9]’ file
[^list] 匹配字符集以外的字元
匹配非o字元,grep -n ‘[^o]’ file
{n1,n2} 前面的單個字元重複n1,n2次
匹配google,gooogle,grep -n ’ go{2,3}gle ’ file
<word 單詞的開頭
匹配以g開頭的單詞,grep -n <g file
word> 單詞的結尾
匹配以tion結尾的單詞,grep -n tion> file
‘ ‘ 強引用,引號內的內容不變
“ ” 弱引用,變數會替換
[[:alnum:]] 代表英文大小寫字元及數字,即 0-9, A-Z, a-z
[[:alpha:]] 代表任何英文大小寫字元,即 A-Z, a-z
[[:space:]] 任何會產生空白的字元,包括空白鍵, [Tab] 等等
[[:digit:]] 代表數字,即 0-9
[[:lower:]] 代表小寫字元,即 a-z
[[:upper:]] 代表大寫字元,即 A-Z

egrep及擴充套件正則表示式

grep一般情況下支援基本正則表示式,可以通過引數-E支援擴充套件正則表示式,另外grep單獨提供了一個擴充套件命令叫做egrep用來支援擴充套件正則表示式,這條命令和grep -E等價(grep -E == egrep)
一般情況下,基本正則表示式就夠用了
特殊情況下,複雜的擴充套件表示式,可以簡化字串的匹配
擴充套件正則表示式就是在基本正則表示式的基礎上,增加了一些元資料

元資料 意義和範例
+ 重複前面字元1到多次
匹配god,good,goood等字串,grep -nE go+d’ file
? 匹配0或1次前面的字元
匹配gd,god,grep -nE ‘go?d’ file
| 或or的方式匹配多個字串
匹配god或者good,grep -nE’god
() 匹配整個括號內的字串,原來都是匹配單個字元
搜尋good或者glad,grep -nE 'g(oo
* 前面的字元重複0到多次

例題:

#1、顯示/proc/meminfo檔案中以大小s開頭的行(要求:使用兩種方法) 
cat /proc/meminfo |grep -i "^s" cat /proc/meminfo |grep  "^\(s\|S\)"
 
#2、顯示/etc/passwd檔案中不以/bin/bash結尾的行 
cat /etc/passwd |grep -v ":/bin/bash$"
 
#3、顯示使用者rpc預設的shell程式 
cat /etc/passwd |grep -w "^rpc" |cut -d: -f 7
 
#4、找出/etc/passwd中的兩位或三位數 
cat /etc/passwd |grep -wo "[[:digit:]]\{2,3\}"
 
#5、顯示CentOS7的/etc/grub2.cfg檔案中,至少以一個空白字元開頭的且後面有非空白字元的行 
cat /etc/grub2.cfg | grep "^[[:space:]]\+[^' '].*" cat /etc/grub2.cfg | grep "^[[:space:]]\+[^[:space:]].*"
 
#6、找出“netstat -tan”命令結果中以LISTEN後跟任意多個空白字元結尾的行 
netstat -tan | grep ".*LISTEN[[:space:]]*$"
 
#7、顯示CentOS7上所有系統使用者的使用者名稱和UID 
cat /etc/passwd |cut -d: -f1,3 |grep -w "[1-9][0-9]\{,2\}$"
 
#8、新增使用者bash、testbash、basher、sh、nologin(其shell為/sbin/nologin),找出/etc/passwd使用者名稱和shell同名的行 
cat /etc/passwd |grep -w "^\([^:]*\):.*/\1$"
 
#9、利用df和grep,取出磁碟各分割槽利用率,並從大到小排序 
df |grep "^/dev/sd"|grep -wo "[0-9]\+%"|sort -nr
 
#10、顯示三個使用者root、mage、wang的UID和預設shell 
cat /etc/passwd |grep -w "^\(root\|mage\|wang\)" |cut -d: -f 3,7
 
#11、找出/etc/rc.d/init.d/functions檔案中行首為某單詞(包括下劃線)後面跟一個小括號的行 
cat /etc/rc.d/init.d/functions |grep -i "^\([_[:alnum:]]\+(\)"
 
#12、使用egrep取出/etc/rc.d/init.d/functions中其基名 
echo "/etc/rc.d/init.d/functions" | grep -Eo "[^/]*[/]?$"|tr -d "/"
 
#13、使用egrep取出上面路徑的目錄名 
echo "/etc/rc.d/init.d/" | grep -Eo ".*[/]\<"
 
#14、統計last命令中以root登入的每個主機IP地址登入次數 
last |grep -w "^root.*\<pts" |  grep -wE "((([0-9])|([1-9][0-9])|(1[0-9]{2})|(2[0-4][0-9])| (25[0-5]))[.]){3}(([0-9])|([1-9][0-9])|(1[0-9]{,2})|(2[0-4][0-9])|(25[0-5])){1}[[:space:]]" |tr -s " "|cut -d " " -f3|sort|uniq -c  
 
#15、利用擴充套件正則表示式分別表示0-9、10-99、100-199、200-249、250-255 
[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]
 
#16、顯示ifconfig命令結果中所有IPv4地址 
ifconfig |grep -owE "((([0-9]{1,2})|(1[0-9]{2})|(2[0-4][0-9])|(25[0-5]))[.]){3}(([0-9] {1,2})|(1[0-9]{,2})|(2[0-4][0-9])|(25[0-5])){1}[[:space:]]"
 
#17、將此字串:welcome to  magedu linux 中的每個字元去重並排序,重複次數多的排到前面 
cat test | grep -o "[[:lower:]]"|sort |uniq -c|sort -nr |tr -s ' ' | cut -d " " -f 3 |tr -d '\n'
 
#18.找出ifconfig命令結果中的1-255之間的數字 
ifconfig | grep -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>" 
#步驟拆解 #2 
#25 
#255    
要注意規律 
#ifconfig | grep -E "\<([1-9]|[1-9][0-9])\>"    #| 為或 
#ifconfig | grep -E '\<(1[0-9][0-9])\>'     
#ifconfig | grep -E '\<(2[0-4][0-9]|25[0-5])\>' 

擷取檔案test內的內容:
"Open Source" is a good mechanism to develop programs.
apple is my favorite food.
Football game is not use feet only.
this dress doesn’t fit me.
However, this dress is about $ 3183 dollars.^M
GNU is free air not free beer.^M
Her hair is very beauty.^M
I can’t finish the test.^M
Oh! The soup taste good.^M
motorcycle is cheap than car.
This window is clear.
the symbol ‘*’ is represented as start.
Oh! My god!
The gd software is a library for drafting programs.^M
You are the best is mean you are the no. 1.
The world is the same with “glad”.
I like dog.
google is the best tools for search keyword.
goooooogle yes!
go! go! Let’s go.
# I am ghost

#19. 取得 test 或 taste 這兩個單字相關資訊及行號 
grep -n 't[ae]st' test

#20.不想取 oo 前面有 g 的字元相關資訊及行號
grep -n 'oo' test | grep -v 'goo' 

#21.oo 前面不想要有小寫的字元相關資訊及行號 
grep -n 'oo' test | grep -v '[[:lower:]]oo'

#22.取得行尾結束為小數點相關資訊及行號
grep -n '\.$' test 

#23.取得空白行相關資訊及行號
grep -n '^$' test

#24.取得g??d 的字元相關資訊及行號
grep -n 'g..d' test

#25.取得至少兩個 o 以上的字元相關資訊及行號
grep -n 'o\{2\}' test

#26.取得開頭與結尾都是 g ,兩個g 之間僅能存在至少一個 o 相關資訊及行號
grep -n 'go*g' test

#27.取得g 開頭與 g 結尾的字元,當中的字元可有可無 相關資訊及行號
grep -n 'g.*g' test

#28.取得g 後面連線2到5個 o,然後再接一個 g 的字元相關資訊及行號
grep -n 'go\{2,5\}g' test

sort 排序

sort 就是將檔案的每一行作為一個單位,相互比較,比較原則是從首字元向後,依次按ASCII碼值進行比較,最後將他們按升序輸出。
sort 引數 檔案(-o 輸出檔案)

引數 作用
-b 忽略每行開頭空格字元
-c 檢查檔案是否已按順序排序
-f 忽略大小寫
-M 將前三個字母按月份進行排序
-n 依照數值大小進行排序
-o 輸出檔案
-r 以從大到小排序
-t <分隔符> 指定排序區間分隔符
-k 選擇排序區間
-u 去除重複項

sort

[[email protected] project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[[email protected] project]# sort test1
android
apple
baidu
google
sohu
xiaomi
xunlei

sort -u 去除重複行

[[email protected] project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[[email protected] project]# sort -u test1
android
apple
baidu
google
sohu
xiaomi
xunlei

當-u和-k一起使用時,sort只會對-k引數指定的部分進行比較,若-k指定部分相同則一樣會過濾掉不輸出。

sort -r 將檔案降序排列

[[email protected] project]# cat test1
apple
xiaomi
google
apple
baidu
sohu
android
xunlei
[[email protected] project]# sort -r test1
xunlei
xiaomi
sohu
google
baidu
apple
android

sort -o 將檔案內容排序並輸出到另一個檔案

由於sort預設是把結果輸出到標準輸出,所以需要用重定向才能將結果寫入檔案,形如sort filename > newfile。
但如果想把排序結果輸出到原檔案中,用重定向可就不行了。
[[email protected] programming]$ sort -r number > number
[[email protected] programming]$ cat number
[[email protected] programming]$
number清空了!!!
所以在這裡我們就需要用-o引數

[[email protected] project]# cat number
1
3
5
2
4
[[email protected] project]# sort -r number -o number
[[email protected] project]# cat number
5
4
3
2
1

sort -n 以數值number大小排序

[[email protected] project]# cat number 
3
25
1
564
43
47
234
4
56725
1
324
4
32
[[email protected] project]# sort number 
1
1
234
25
3
32
324
4
4
43
47
564
56725
[[email protected] project]# sort -n number 
1
1
3
4
4
25
32
43
47
234
324
564
56725

sort -t 以指定的分隔符排序 -k 以指定的列進行排序

在sort排序中,-t如果不指定分隔符時,一般預設以空格作為分隔符
sort中-t和-k一般結合使用,例如:

[[email protected] project]# cat test3
apple:50:5000
android:60:6000
google:100:5500
baidu:110:5500
sohu:55:7000
xiaomi:65:4000
xunlei:50:6000
[[email protected] project]# sort -n -t: -k2 test3
apple:50:5000
xunlei:50:6000
sohu:55:7000
android:60:6000
xiaomi:65:4000
google:100:5500
baidu:110:5500

例題:

[[email protected] project]# cat test2
apple 50 5000
android 60 6000
google 100 5500
baidu 110 5500
sohu 55 7000
xiaomi 65 4000
xunlei 50 6000

以空格作為分隔符,以第二列資料作為排序標準,若第二列中有重複資料則比較第三列:

[[email protected] project]# sort -n -t' ' -k 2,3 test2
apple 50 5000
xunlei 50 6000
sohu 55 7000
android 60 6000
xiaomi 65 4000
google 100 5500
baidu 110 5500

以空格作為分隔符,只以第一列的第二位作為排序標準,若有重複資料則只比較第三列:

[[email protected] project]# sort -n -t' ' -k 1.2,1.2 -k 3,3 test2
xiaomi 65 4000
apple 50 5000
baidu 110 5500
google 100 5500
android 60 6000
xunlei 50 6000
sohu 55 7000
注意這個例子
[[email protected] project]# sort -n -k 2.2,3.1 test2
apple 50 5000
android 100 6000
google 100 5500
baidu 110 5500

以第二個域的第二個字元開始到第三個域的第一個字元結束的部分進行排序。
第一行,會提取0 5,第二行提取00 6,第三行提取00 5,第四行提取10 5。
又因為sort認為0小於00小於000小於0000….

原因:sort只會比較第二個域的第二個字元到第二個域的最後一個字元的部分,而不會把第三個域的開頭字元納入比較範圍。當發現00和00相同時,sort就會自動比較第一個域去了。當然baidu在sohu前面了。
用一個範例即可證實:

[[email protected] project]# sort -n -k 2.2,3.1 -k3.1 test2
apple 50 5000
google 100 5500
android 100 6000
baidu 110 5500

diff 命令

diff 命令用於比較多個文字檔案的差異,格式為“diff [選項] 檔案”。

使用 cat 命令分別檢視 diff_A.txt 和 diff_B.txt 檔案的內容,然後進行比較:

[[email protected] ~]# cat diff_A.txt Welcome to linux.com
Red Hat certified Free Linux Lessons
[[email protected] ~]# cat diff_B.txt


Welcome to linux.com #Red Hat certified
Free Linux Lessons

使用 diff --brief 命令顯示比較後的結果,判斷檔案是否相同:

[[email protected] ~]# diff --brief diff_A.txt diff_B.txt 
Files diff_A.txt and diff_B.txt differ

使用帶有-c 引數的 diff 命令來描述檔案內容具體的不同:

[[email protected] ~]# diff -c diff_A.txt diff_B.txt
*** diff_A.txt  2018-08-16 05:54:38.440500149 -0400
--- diff_B.txt   2018-08-16 05:55:09.921497634 -0400
***************
*** 1,3 ****
Welcome to linux.com
! Red Hat certified Free Linux Lessons
--- 1,3 ----
Welcome to linux.com
! #Red Hat certified

Free Linux Lessons

使用 diff 命令結合後面要講的重定向,生成一個補丁檔案,其中,字母"a"、“d”、"c"分別表示新增、刪除及修改操作。

[[email protected] mnt]# diff diff_A.txt diff_B.txt 1,3c1,3
< Welcome to linux.com
< #Red Hat certified
< Free Linux Lessons
---
> Welcome tooo linux.com
> Red Hat certified
> Free Linux LeSSonS
[[email protected] mnt]# diff diff_A.txt diff_B.txt > path.file [[email protected] mnt]# cat path.file
2c2
< Red Hat certified
---
> #Red Hat certified
引數 作用
-u 顯示有差異行的前後幾行(上下文), 預設是前後各 3 行, 這樣,
patch 中帶有更多的資訊.,
-p 顯示程式碼所在的 c 函式的資訊。
-r 遞迴地對比一個目錄和它的所有子目錄(即整個目錄樹)。
-N 如果某個檔案缺少了, 就當作是空檔案來對比. 如果不使用本選項, 當 diff 發現舊程式碼或者新程式碼缺少檔案時, 只簡單的提示缺少檔案. 如果使用本選項, 會將新新增的檔案全新打印出來作為新增的部分.

patch 命令

patch 被用於為開放原始碼軟體安裝補丁程式。讓使用者利用設定修補檔案的方式,修改,更新原始檔案。

使用 diff 命令生成的 patch.file 為 diff_A.txt 升級或者還原

[[email protected] mnt]# patch diff_A.txt < path.file patching file diff_A.txt
[[email protected] mnt]# patch -R diff_A.txt < path.file patching file diff_A.txt

tr 命令

tr 命令用於替換文字檔案中的字元,格式為“tr [原始字元] [目標字元]”。

把某個文字內容中的英文全部替換為大寫

[[email protected] ~]# cat anaconda-ks.cfg | tr [a-z] [A-Z] #VERSION=DEVEL
# SYSTEM AUTHORIZATION INFORMATION AUTH --ENABLESHADOW --PASSALGO=SHA512


# USE CDROM INSTALLATION MEDIA CDROM
# USE GRAPHICAL INSTALL GRAPHICAL
# RUN THE SETUP AGENT ON FIRST BOOT FIRSTBOOT --ENABLE
IGNOREDISK --ONLY-USE=SDA # KEYBOARD LAYOUTS
KEYBOARD --VCKEYMAP=US --XLAYOUTS='US' # SYSTEM LANGUAGE
LANG EN_US.UTF-8

# NETWORK INFORMATION
NETWORK --BOOTPROTO=DHCP --DEVICE=ENO16777728 --ONBOOT=OFF -- IPV6=AUTO
NETWORK --HOSTNAME=linux.COM

# ROOT PASSWORD ROOTPW --ISCRYPTED
$6$HFRQIKOPAK5JQAWM$AVUYZ3JQZ4WAWCPLRHBPM08GNDZRBIVU2BG.RTM IXVZODSZK/PFUZJ8OKEWE0MDCX66OK3/BNYWKYGAIPGUFP.
# SYSTEM TIMEZONE


TIMEZONE AMERICA/NEW_YORK  --ISUTC # SYSTEM BOOTLOADER CONFIGURATION
BOOTLOADER --APPEND=" CRASHKERNEL=AUTO" --LOCATION=MBR --BOOT- DRIVE=SDA
AUTOPART --TYPE=LVM
# PARTITION CLEARING INFORMATION CLEARPART --ALL --INITLABEL --DRIVES=SDA

%PACKAGES @^MINIMAL @CORE KEXEC-TOOLS

%END

%ADDON COM_REDHAT_KDUMP --ENABLE --RESERVE-MB='AUTO'

%END

Bash指令碼

顯示訊息echo

[[email protected] ~]# cat s2.sh
#!/bin/bash 
#The examples of echo command 
# 
echo "The time is:"     #字串需要用''或""引起來 
date echo "The who's logged on:" 
who

[[email protected] ~]# sh s2.sh 
The time is:
Wed Oct 31 16:51:14 CST 2018
The who's logged on:
root     tty1         2018-10-31 16:03
root     pts/0        2018-10-31 16:02 (192.168.130.1)

使用變數

[[email protected] ~]# cat s3.sh
#!/bin/bash 
#The examples of '$' 
# 
echo "The user is: $USER"   #echo中可以使用$變數 
echo "The user id is: $UID" 
echo "The user directory is: $HOME"

[[email protected] ~]# sh s3.sh 
The user is:root
The user id is:0
The user directory is:/root

使用者變數

[[email protected] ~]# cat s4.sh
#!/bin/bash
days=10
guest='alice'
echo "The user $guest logged system before $days days ago"
days=5
guest="tom"
echo "The user $guest logged system before $days days ago"

[[email protected] ~]# sh s4.sh 
The user alice logged system before 10 days ago
The user tom logged system before 5 days ago

命令替換

[[email protected] ~]# cat s5.sh
#!/bin/bash
time=$(date +%F-%T)
cp -a /var/log/messages /tmp/messages_bak.$time

[[email protected] ~]# sh s5.sh 
[[email protected] ~]# cd /tmp/
[[email protected] tmp]# ls
messages_bak.2018-10-24-16:52:23

數學運算

[[email protected] ~]# cat s6.sh
#!/bin/bash
var1=10
var2=20.23
result=$(echo "scale=2; $var1 + $var2" | bc)

echo The result is $result

[[email protected] ~]# sh s6.sh 
The result is 30.23

[[email protected] ~]# cat s7.sh
#!/bin/bash
var1=10.46
var2=43.67
var3=33.2
var4=71
result=$(bc << EOF
scale = 4
a1 = ($var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo $result
[[email protected] ~]# sh s7.sh 
2813.9882

Bash條件測試

[[email protected] ~]# cat s8.sh 
#!/bin/bash
t_user=alice
if grep $t_user /etc/passwd
then
        echo "The user name is:$USER"
        echo "The user uid is:$UID:"
        echo "Other dir info are:"
        ls -a /home/$t_user/.b*
fi

[[email protected] ~]# sh s8.sh 
alice:x:10005:10008::/home/alice:/bin/bash
The user name is:root
The user uid is:0:
Other dir info are:
/home/alice/.bash_history  /home/alice/.bash_profile
/home/alice/.bash_logout   /home/alice/.bashrc



[[email protected] ~]# cat s9.sh 
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
else
        echo "The user $t_user does not exist on system."
fi

[[email protected] ~]# sh s9.sh 
The user aaa does not exist on system.



[[email protected] ~]# cat s10.sh 
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
elif ls -d /home/$t_user
then
        echo "The user $t_user does not exist on system."
        echo "However, $t_user has a directory."
fi

[[email protected] ~]# sh s10.sh 
ls: cannot access /home/aaa: No such file or directory



[[email protected] ~]# cat s101.sh     #elif中巢狀
#!/bin/bash
t_user=aaa
if grep $t_user /etc/passwd
then
        echo "The user $t_user exists on system"
elif ls -d /home/$t_user
then
        echo "The user $t_user does not exist on system."
        echo "However, $t_user has a directory."
else
        echo "The user $t_user does not exist on system."
        echo "And,$t_user does not have a directory."
fi

[[email protected] ~]# sh s101.sh 
ls: cannot access /home/aaa: No such file or directory
The user aaa does not exist on system.
And,aaa does not have a directory.


[[email protected] ~]# cat s11.sh 
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/testing ] #-d檢查file是否存在且是一個目錄,-w可寫
then
        echo "The file exists and you can write to it"
else
        echo "I can not write to the file"
fi 

[[email protected] ~]# sh s11.sh 
I can not write to the file


[[email protected] ~]# cat s12.sh 
#!/bin/bash
value1=10
value2=11
if [ $value1 -gt 5 ]
then 
        echo "The value $value1 is greater than 5"
fi
if [ $value1 -eq $value2 ] 
then
        echo "The values are equal"
else 
        echo "The values are different"
fi

[[email protected] ~]# sh s12.sh 
The value 10 is greater than 5
The values are different

Bash練習

1.顯示當前主機系統資訊,包括主機名,IPv4地址,作業系統版本,核心版本,CPU型號,記憶體大小,硬碟大 小,儲存指令碼為sys_info.sh

#!/bin/bash
echo "System Device Info"
echo "------------------------"
var1=`hostname`
echo "localhost name:$var1"
var2=`ifconfig | grep 'inet' | grep -v 'inet6' | sed 's/^.*inet//g' | sed 's/netmask.*//g'`
echo "ip address:$var2"
var3=`cat /etc/redhat-release`
echo "Os info:$var3"
var4=`uname -a | cut -d' ' -f 3`
echo "Kernel info:$var4"
var5=`cat /proc/cpuinfo | grep "model name" | cut -d' ' -f 3,4,5,6,7,8` 
echo "cpu info:$var5"
var6=`free -h | grep "Mem" | cut -d' ' -f12`
echo "Memory info:$var6"
var7=`fdisk -l | grep "Disk /dev/sda" | cut -d',' -f 1`
echo "Disk info:$var7"

2.將/etc/目錄備份到/tmp下,並以此格式儲存bak_etc_yyyy-mm-dd,儲存為指令碼bak_etc.sh

#!/bin/bash
cp -r /etc /tmp/bak_etc_`date +%F`

3.顯示當前硬碟分割槽中空間利用率大的值,儲存指令碼為disk_used.sh

#!/bin/bash
disk_usage=`df |tr -s " " | cut -d' ' -f 5 | sort -n | tail -n1`
echo "The max disk used : $disk_usage"

4.顯示正連線本主機的每個遠端主機的IPv4地址和連線數,並按連線數從大到小排序,儲存指令碼為link.sh

#!/bin/bash
netstat -tn | tr -s " " | cut -d " " -f 5| cut -d : -f 1 | sort -nr | uniq -c 

5.計算/etc/passwd檔案中的第5個使用者和第15使用者的ID之和,儲存指令碼為sum_id.sh

#!/bin/bash
var1=`head -n5 /etc/passwd | tail -n1 | cut -d ':' -f3`
var2=`head -n15 /etc/passwd | tail -n1 | cut -d ':' -f3`
let Num=$var1+$var2
echo $Num

6.統計/etc, /var, /usr目錄中共有多少檔案,儲存指令碼為sum.sh

#!/bin/bash
var1=`ls -l /etc/ | wc -l`
echo "/etc/:$var1"
var2=`ls -l /var/ | wc -l`
echo "/var/:$var2"
var3=`ls -l /usr/ | wc -l`
echo "/usr/:$var3"
let sum=$var1+$var2+$var3
echo "sum="$sum

7.接受一個主機的IPv4地址做為引數,測試是否可連通。如果能ping通,則輸出“該IP地址可訪問”;如果不可 ping通,則輸出“該IP地址不可訪問”,儲存指令碼為ping.sh

#!/bin/bash
ipaddr='(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))\>\.){3}\<([0-9]|[1-9][0-9]|1[0-5][1-9]|2([0-4][0-9]|25[0-5]))\>'
    read -p "please input a IPV4 addr: " ipv4
    if [[ $ipv4 =~ $ipaddr ]];then
        ping $ipv4 -c 4 && echo "這個IP可以正常訪問"||echo "這個IP不能訪問"
    else
        echo "請輸入正確的網址"
        exit
    fi