數值運算 條件測試 、 if選擇結構

“ ”雙引 引整體
“a b c” != a b c
abc == “abc” 以後最好加“”,防止出現錯誤

‘’ 單引 引整體,屏蔽特殊符號 ‘abc’
[root@localhost test]# a=12
[root@localhost test]# echo "$a RMB"
12 RMB
[root@localhost test]# echo '$a RMB'
$a RMB

\ 把它右邊的符號屏蔽掉
[root@localhost test]# a=12
[root@localhost test]# echo "\$a RMB"
$a RMB
[root@localhost test]# echo "\$a $a $a $a"
$a 12 12 12

echo a b c 這是不同的 計算機理解是a,b,c
echo 'abc' 計算機理解是a b c

看不清有幾個文件 ll

[root@localhost ~]# mkdir test
[root@localhost ~]# cd /test
-bash: cd: /test: 沒有那個文件或目錄
[root@localhost ~]# cd test
[root@localhost test]# touch "a b c"
[root@localhost test]# ls
a b c
[root@localhost test]# rm -rf a b c
[root@localhost test]# ls
a b c
[root@localhost test]# rm -rf "a b c"
[root@localhost test]# ls

``反引 引用的是命令,提取命令的結果

計劃任務:每週五對日誌備份一次,備份到/root
crontab -e //edit
11 03 */5 tar -zcf /root/log.tar.gz /var/log

( 5 每週五每分都在備份 ,一定要給個具體時間
#同樣的文件名字會覆蓋# 文件名要是變量 ,文件的後綴最好是時間)

date +s 修改時間
--set=STRING
set time described by STRING

[root@localhost test]# date +"%Y%m%d"
20170409

date +"%Y%m%d"=20170409

11 03 */5 tar -zcf log-date +"%Y%m%d".tar.gz /var/log
log -(添加識別的關鍵字)

[root@localhost test]# tar -zcf log-date +"%Y%m%d".tar.gz /var/log
tar: 從成員名中刪除開頭的“/”
[root@localhost test]# ls
20170409.tar.gz log-20170409.tar.gz

變量

寫腳本,寫定義變量,但不賦值,執行腳本再賦值

read -p "提示信息" 變量

read 變量
[root@localhost test]# read abc
yy()
[root@localhost test]# echo $abc
yy

read -p "請輸入用戶名:" user (""中的內容是提示符)

寫一個腳本,提示用戶輸入用戶和密碼
根據用戶的輸入創建賬戶和密碼
[root@localhost ~]# vim test1.sh
#!/bin/bash
read -p "請輸入用戶名:" user
useradd $user
read -p "請輸入密碼:" pass
echo "$pass" | passwd --stdin $user

[root@localhost ~]# bash test1.sh
請輸入用戶名:sanpao
請輸入密碼:456
更改用戶 sanpao 的密碼 。
passwd:所有的身份驗證令牌已經成功更新。

#密碼明文顯示#

stty -echo 不顯示
stty echo 回顯
#在某個位置不打開回顯,一定要再打開。否則以後會很麻煩。

不顯示密碼
#!/bin/bash
read -p "請輸入用戶名:" user
stty -echo
read -p "請輸入密碼:" passwd
stty echo
useradd $user
echo $passwd | passwd --stdin $user

1.變量
全局變量 (export 輸出)
[root@localhost ~]# export a=12
[root@localhost ~]# bash
[root@localhost ~]# bash
[root@localhost ~]# echo $a
12

[root@localhost ~]# b=12
[root@localhost ~]# export b
[root@localhost ~]# bash
[root@localhost ~]# bash
[root@localhost ~]# echo $b
12

自己寫腳本局部變量,系統自帶的全局變量

局部變量

Top
NSD SHELL DAY02

1.整數運算
expr 數字 數學符號 數字 (不好用)
[root@localhost ~]# expr 1 + 2
3
[root@localhost ~]# expr 1+ 2
expr: 語法錯誤

支持+ - * / %【取餘數】求模運算
[root@localhost ~]# expr 5 % 3
2

$((數字符號數字)) 或者 $[數字符號數字] 沒有回顯功能
[root@localhost ~]# echo $((12))
2
[root@localhost ~]# echo $[3
2]
6

[root@localhost ~]# a=12
[root@localhost ~]# b=2
[root@localhost ~]# echo $[a+b]
14

let 數字符號數字 不帶回顯功能
[root@localhost ~]# let c=a+b
[root@localhost ~]# echo $c
14

++【不會單獨用,會跟動作一起用,做計數器】 -- ===>>每次只是+1或是-1
+= -= *= /= ===>>等於號後面賦予變量的值

1+2 2元運算
x++ 1元運算

a=2
let a++ # a=a+1
[root@localhost ~]# a=2
[root@localhost ~]# let a++
[root@localhost ~]# echo $a
3
[root@localhost ~]# let a++
[root@localhost ~]# echo $a
4

+=
a=2
let a+=2 a=a+2
[root@localhost ~]# a=2
[root@localhost ~]# let a+=2
[root@localhost ~]# echo $a
4
[root@localhost ~]# let a+=2
[root@localhost ~]# echo $a
6
[root@localhost ~]# let a+=6
[root@localhost ~]# echo $a
12
[root@localhost ~]# let a-=1
[root@localhost ~]# echo $a
11
[root@localhost ~]# let a-=1
[root@localhost ~]# echo $a
10
[root@localhost ~]# let a*=2
[root@localhost ~]# echo $a
20
[root@localhost ~]# let a/=10
[root@localhost ~]# echo $a
2

2.小數運算
%【取餘數】求模運算 #餘數一定會小於被除數#
bc計算器
交互
非交互
需告知小數點後留有幾位scale
[root@localhost ~]# echo "scale=2;3.000000005/2.15" | bc
1.39

[root@localhost ~]# echo "scale=2;3/10" | bc
.30

[root@localhost ~]# echo "scale=4;3.5*2.81" | bc
9.835

man text
SYNOPSIS
test EXPRESSION
test

   [ EXPRESSION ]
   [ ]
   [ OPTION

3.測試 更加智能

test 表達式
[ 表達式 ] 1)字串 2)數字 3)文件、目錄

能測試哪些東西
1.字符串測試 【-z 檢查變量的值是否設置】
[ -z $變量 ]
-z STRING 字串
the length of STRING is zero 測字串是否爲空
-z 字符串的值爲空
-n 字符串的值不爲空(相當於! -z )

[root@localhost ~]# a=12
[root@localhost ~]# [ -z $a ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ -z $ttttttt ]
[root@localhost ~]# echo $?
0

同一行打多個命令【多個命令,最好從後面往前分析】
1.&& 並且 A && B 【並且】
只有A成功了,纔會去執行B,B不一定會成功;若A不成功,則B不執行。
給定的條件必須都成立,整個測試結果才爲真。

2.|| 或者 A || B
如A成功,則不執行B。如A不成功,則執行B。
只要其中的一個條件成立,則整個測試結果爲真。

3.分號; A;B 不管A成不成功都執行B
A && B | C && D
A肯定會執行

[root@localhost ~]# [ -z $rrrrrr ] && echo yes || echo no
yes
[root@localhost ~]# [ -z $a ] && echo yes || echo no
no

A && B A成功=》B
A || B
[ -z $ttttttt ] && echo y || echo n
A && B || C

寫腳本,如果用戶不輸入用戶名,則腳本退出
-s silent 有回顯

#!/bin/bash
read -p "請輸入用戶名:" user
[ -z $user ] && echo "您沒有輸入用戶名" && exit
stty -echo
read -s -p "請輸入密碼:" password 【-s選項能夠使read命令中輸入的數據不顯示在監視器上(實際上數據是顯示的,只是read命令將文本顏色設置成與背景相同的顏色)】
stty echo
[ -z $password ] && echo "您沒有輸入密碼" && exit

useradd $user
echo $password | passwd --stdin $user

能測試哪些
1.字符串
[ -z $abc ]是否爲空 【答案取反】

[ ! -z $abc ] 是否非空 【答案正常】

a=12
[ ! -z $a ] 對,不是空
$?(對,錯)

[root@localhost ~]# a=12
[root@localhost ~]# [ -z $a ] $a是空的嗎?
[root@localhost ~]# echo $?
1 錯,$a不是空的
[root@localhost ~]# [ -z $zz ] $zz
[root@localhost ~]# echo $?
0 $zz
[root@localhost ~]# [ ! -z $a ]
[root@localhost ~]# echo $?
0

測試基本不用常量
[ a == b ] 是否相同
[ a != b ] 是否不同
[root@localhost ~]# [ $USER == root ]
[root@localhost ~]# echo $?
0

2.數字
等於 equal eq
不同等於 not equal ne 【納特】
小於 less than lt
小於等於 less equal le
大於 greater than gt
大於等於 greater equal ge

寫腳本 腳本自動生成10以內隨機數,讓用戶猜是多少
腳本自動判斷,對和錯
RANDOM 隨機生成數

餘數% ## echo $[RANDOM%10]

猜 read

#! /bin/bash

num=$[RANDOM%10] 將值固定死!
read -p "我有一個隨機數,讓你猜:" guest
[ $num -eq $guest ] && echo "恭喜你,答對了。" || echo "哎喲,錯了。"

寫腳本 腳本自動生成10以內隨機數,讓用戶猜是多少
腳本判斷,給出提示大於,小於,等於

vim text.sh

vim

3.文件或目錄測試

[ -d 文件或目錄 ] 測試是否存在且爲目錄 directory
[ -f 文件或目錄 ] 測試是否存在且爲文件 file
[ -e 文件或目錄 ] 測試是否存在 exist
[ -s 文件 ] 測試是大小是否大與0 size

[ -r 文件 ]
[ -w 文件 ]
[ -x 文件 ]
誰執行的腳本測誰

檢測目錄是否存在,不存在自動創建abc
mount -o loop ISO /abc

#!/bin/bash
[ -d /nmt ] || mkdir /mnt
mount -o loop /ISO/rhel-server-7.2-x86_64-dvd.iso /mnt
[ -e 找7.2中隨機一個文件是否存在 ]

每分鐘測試當前登陸用戶數量,是否大於3
如果大於3,則發送郵件報警
1)當前幾個人登陸

wc=word count 字數統計 -l = --line
-c = --char 字符

[root@room4pc09 桌面]# who
root :0 2017-04-10 07:33 (:0)
root pts/1 2017-04-10 14:46 (:0)
root pts/2 2017-04-10 08:26 (:0)
root pts/3 2017-04-10 17:18 (:0)
[root@room4pc09 桌面]# who | wc -l
4

vim test.sh
num=who | wc -l ##注意反引號
[ $num -gt 3 ] && mail -s 標題 root < 文件

crondtab -e

          • /root/test.sh

計劃任務,每分鐘執行該腳本
#!/bin/bash
user=who |wc -l
[ $user -gt 3 ] && mail -s Error root < /etc/passwd
發送給root,如果公司連網,也可以發送[email protected]【發送給自己的郵箱】

crondtab -e

          • /root/test.s
            【test.sh 如果沒給權限會收到報錯信息】

if語法格式
1.單分支【對】
if [ ];then
命令
fi
也可以:
if [ ]
then
命令
fi

[root@localhost ~]# df -h
文件系統 容量 已用 可用 已用% 掛載點
/dev/mapper/rhel-root 50G 3.0G 48G 6% /
devtmpfs 482M 0 482M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 7.0M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/mapper/rhel-home 38G 33M 38G 1% /home
/dev/vda1 497M 158M 340M 32% /boot
tmpfs 100M 0 100M 0% /run/user/0

【寫腳本最好不用-h!!給人看的加-h】
[root@localhost ~]# df
文件系統 1K-塊 已用 可用 已用% 掛載點
/dev/mapper/rhel-root 52403200 3091040 49312160 6% /
devtmpfs 492924 0 492924 0% /dev
tmpfs 508456 0 508456 0% /dev/shm
tmpfs 508456 7164 501292 2% /run
tmpfs 508456 0 508456 0% /sys/fs/cgroup
/dev/mapper/rhel-home 39245084 33152 39211932 1% /home
/dev/vda1 508588 160796 347792 32% /boot
tmpfs 101692 0 101692 0% /run/user/0

如何直接取其中一行 df 目錄 或 df | grep "root"
[root@localhost ~]# df /
文件系統 1K-塊 已用 可用 已用% 掛載點
/dev/mapper/rhel-root 52403200 3091032 49312168 6% /
[root@localhost ~]# df /boot
文件系統 1K-塊 已用 可用 已用% 掛載點
/dev/vda1 508588 160796 347792 32% /boot

[root@localhost ~]# df | grep "root"
/dev/mapper/rhel-root 52403200 3091020 49312180 6% /
[root@localhost ~]# nu=49312180:
[root@localhost ~]# if [ $nu -lt 40000 ];then

echo Error
fi

#!/bin/bash
nu=49312180
if [ $nu -le 4000 ];then
echo Error
fi
如果磁盤容量小於等於4000,則報警!

2.雙分支 【對,錯】【非對即錯】
if [ ];then
命令
else
命令
fi

###判斷httpd是否開啓,如果開啓提示YES,沒有開啓提示NO###
systemctl status
1.看端口:80

[root@localhost httpd]# systemctl restart httpd
[root@localhost httpd]# netstat -anptu | grep 80
tcp6 0 0 :::80 :::* LISTEN 9035/httpd

[ -z $a ] //當$a取值太多的話,會顯示錯誤,這時一定要用“”引上, 即[ -z "$a" ]
rpm -

[root@localhost ~]# vim test-httpd80.sh
#!/bin/bash
netstat -ntulp | grep http > /dev/null

if [ $? -eq 0 ] //如果[ $? == 0 ] ,會把==兩端的字符串當作兩個數字進行比較。
then
echo yes
else
echo no

fi

2.看pid (/var/run/)
[root@localhost ~]# vim test-httpd.sh
:#!/bin/bash
if [ -f /var/run/httpd/httpd.pid ]
then echo "YES"
else echo "NO"
fi

netstat -ntulp | grep httpd

###./test.sh 192.168.4.5(參數)###
腳本自動判斷該IP是否能ping通。

vim test-ping.sh
#!/bin/bash
read -p "請輸入IP地址:" IP
ping -c 2 $IP &> /dev/null //-c count次數
if [ $? -eq 0 ]
then
echo "通了。"
else
echo "不通。"

fi
~

[root@localhost ~]# ping -c 2 -i 0.1 192.168.4.1 //-i 單位是秒。間隔0.1秒。
PING 192.168.4.1 (192.168.4.1) 56(84) bytes of data.
64 bytes from 192.168.4.1: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 192.168.4.1: icmp_seq=2 ttl=64 time=0.053 ms

--- 192.168.4.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 100ms
rtt min/avg/max/mdev = 0.044/0.048/0.053/0.008 ms

3.多分支(多種可能性)
if [ ];then
命令
elif [ ];then
命令
elif [ ];then
命令
else 【否則,其他的意思】
命令
fi

read -p "請輸入一個字母:" key
if [ $key == a ];then
echo "你輸入的是a"
if [ $key == b ];then
echo "你輸入的是b"
if [ $key == c ];then
echo "你輸入的是c"
else
echo "你輸入的不是abc。"
fi

【常見錯誤】
##echo $[ ] 這個運算中不能有小數點。有小數點的數只能在bc中。
[root@localhost ~]# [ abc ]
[root@localhost ~]# echo $?
0

案例1:Shell中的數值運算
案例2:條件測試操作
案例3:使用if選擇結構

1 案例1:Shell中的數值運算
1.1 問題

本案例要求熟悉Linux Shell環境的特點,主要練習以下操作:

使用expr、$[ ]、let等整數運算工具:定義變量X=1234,然後計算X與78的四則運算及求模結果
使用bc實現小數運算操作:以交互方式計算12.34與56.78的四則運算結果,另外再以非交互方式重複上述計算,最多顯示4位小數

1.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:整數運算工具

1)使用expr命令

乘法操作應採用 * 轉義,避免被作爲Shell通配符;參與運算的整數值與運算操作符之間需要以空格分開,引用變量時必須加$符號。

首先定義變量X=1234,然後分別計算與78的加減乘除和求模運算結果:

[root@svr5 ~]# X=1234                              //定義變量X
[root@svr5 ~]# expr  $X  +  78                      //加法
1312
[root@svr5 ~]# expr  $X  -  78                       //減法
1156
[root@svr5 ~]# expr  $X  \*  78                      //乘法,操作符應添加\轉義
96252
[root@svr5 ~]# expr  $X  /  78                      //除法,僅保留整除結果
15
[root@svr5 ~]# expr  $X  %  78                     //求模
64

2)使用$[ ]或$(())表達式

乘法操作*無需轉義,運算符兩側可以無空格;引用變量可省略 $ 符號;計算結果替換表達式本身,可結合echo命令輸出。

同樣對於變量X=1234,分別計算與78的加減乘除和求模運算結果:

[root@svr5 ~]# X=1234   
[root@svr5 ~]# echo $[X+78]
1312
[root@svr5 ~]# echo $[X-78]
1156
[root@svr5 ~]# echo $[X*78]
96252
[root@svr5 ~]# echo $[X/78]
15
[root@svr5 ~]# echo $[X%78]
64

3)使用let命令

expr或$[]、$(())方式只進行運算,並不會改變變量的值;而let命令可以直接對變量值做運算再保存新的值。因此變量X=1234,在執行let運算後的值會變更;另外,let運算操作並不顯示結果,但是可以結合echo命令來查看:

[root@svr5 ~]# X=1234  
[root@svr5 ~]# let X+=78 ; echo $X
1312
[root@svr5 ~]# let X-=78 ; echo $X 
1234
[root@svr5 ~]# let X*=78 ; echo $X 
96252
[root@svr5 ~]# let X/=78 ; echo $X 
1234
[root@svr5 ~]# let X%=78 ; echo $X 
64

步驟二:小數運算工具

1)bc交互式運算

先執行bc命令進入交互環境,然後再輸入需要計算的表達式。以計算小數12.34與5.678的四則運算爲例,相關操作如下:

[root@svr5 ~]# bc 
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
12.34+56.78                                        //加法
69.12
12.34-56.78                                        //減法
-44.44
12.34*56.78                                        //乘法
700.66
12.34/56.78                                        //除法
0
quit                                              //退出交互計算器
[root@svr5 ~]#

2)bc非交互式運算

將需要運算的表達式通過管道操作交給bc運算。注意,小數位的長度可採用scale=N限制,除此以外也受參與運算的數值的小數位影響。以計算小數12.34與5.678的四則運算爲例,相關操作如下:

[root@svr5 ~]# echo 'scale=4;12.34+5.678' | bc
18.018
[root@svr5 ~]# echo 'scale=4;12.34-5.678' | bc 
6.662
[root@svr5 ~]# echo 'scale=4;12.34*5.678' | bc 
70.0665
[root@svr5 ~]# echo 'scale=4;12.34/5.678' | bc 
2.1733

2 案例2:條件測試操作
2.1 問題

本案例要求參考PPT上的示例,分別練習以下條件測試操作:

字符串匹配
比較整數值的大小
識別文件/目錄的狀態
多個條件/操作的邏輯組合

2.2 步驟

實現此案例需要按照如下步驟進行。

步驟一:條件測試的基本用法

1)語法格式

使用“test 表達式”或者[ 表達式 ]都可以,表達式兩邊至少要留一個空格。

條件測試操作本身不顯示出任何信息。測試的條件是否成立主要體現在命令執行後的返回狀態(即 $?),所以可以在測試後查看變量$?的值來做出判斷,或者結合&&、||等邏輯操作顯示出結果(或作其他操作) 。

步驟二:字符串測試

1)== 比較兩個字符串是否相同

檢查當前用戶是否爲root。

當root用戶執行時:

[root@svr5 ~]# [ $USER == "root" ]             //測試
[root@svr5 ~]# echo $?                        //查看結果0爲對,非0爲錯

當普通用戶執行時:

[zengye@svr5 ~]$ [ $USER == "root" ]
NO
[zengye@svr5 ~]$ echo $?

2)!= 比較兩個字符串是否不相同

檢查當前用戶,如果不是root。

當普通用戶執行時:

[zengye@svr5 ~]$ [ $USER != "root" ] 

當root用戶執行時:

[root@svr5 ~]# [ $USER != "root" ]

3)-z 檢查變量的值是否未設置(空值)

[root@svr5 ~]# var1="Tarena" ; var2=""
[root@svr5 ~]# [ -z "$var1" ] && echo "空值" || echo "非空值"
非空值
[root@svr5 ~]# [ -z $var2 ] && echo "空值" || echo "非空值"
空值                                      //變量var2已設置,但無任何值,視爲空
[root@svr5 ~]# [ ! -z $var1 ]                //測試var1是否爲非空 

步驟三:整數值比較

參與比較的必須是整數(可以調用變量),比較非整數值時會出錯:

[root@svr5 ~]# A=20.4
[root@svr5 ~]# [ $A -gt 10 ]                  //不支持小數比較
-bash: [: 20.4: integer expression expected

1)-eq 比較兩個數是否相等。

[root@svr5 ~]# X=20                          //定義一個測試變量
[root@svr5 ~]# [ $X -eq 20 ] && echo "相等" || echo "不相等"
相等
[root@svr5 ~]# [ $X -eq 30 ] && echo "相等" || echo "不相等"
不相等

2)-ne 比較兩個數是否不相等。

[root@svr5 ~]# [ $X -ne 20 ] && echo "不等於" || echo "等於"
等於
[root@svr5 ~]# [ $X -ne 30 ] && echo "不等於" || echo "等於"
不等於

3)-gt 比較前面的整數是否大於後面的整數。

[root@svr5 ~]# [ $X -gt 10 ] && echo "大於" || echo "否"
大於
[root@svr5 ~]# [ $X -gt 20 ] && echo "大於" || echo "否"
否
[root@svr5 ~]# [ $X -gt 30 ] && echo "大於" || echo "否"
否

4)-ge 比較前面的整數是否大於或等於後面的整數。

[root@svr5 ~]# [ $X -ge 10 ] && echo "大於或等於" || echo "否"
大於或等於
[root@svr5 ~]# [ $X -ge 20 ] && echo "大於或等於" || echo "否"
大於或等於
[root@svr5 ~]# [ $X -ge 30 ] && echo "大於或等於" || echo "否"
否

5)-lt 比較前面的整數是否小於後面的整數。

[root@svr5 ~]# [ $X -lt 10 ] && echo "小於" || echo "否"
否
[root@svr5 ~]# [ $X -lt 20 ] && echo "小於" || echo "否"
否
[root@svr5 ~]# [ $X -lt 30 ] && echo "小於" || echo "否"
小於

6)-le 比較前面的整數是否小於或等於後面的整數。

[root@svr5 ~]# [ $X -le 10 ] && echo "小於或等於" || echo "否"
否
[root@svr5 ~]# [ $X -le 20 ] && echo "小於或等於" || echo "否"
小於或等於
[root@svr5 ~]# [ $X -le 30 ] && echo "小於或等於" || echo "否"
小於或等於

7)提取當前登錄的用戶數,比較是否超過5。

[root@svr5 ~]# who | wc -l                      //確認已登錄的用戶數
4
[root@svr5 ~]# N=$(who | wc -l)              //賦值給變量N
[root@svr5 ~]# [ $N -gt 5 ] && "超過了" || echo "沒超過"
沒超過

上述賦值給變量N及與5比較的操作,可以簡化爲如下形式:

[root@svr5 ~]# [ $(who | wc -l) -gt 5 ] && "超過了" || echo "沒超過"
沒超過

步驟四:識別文件/目錄的狀態

1)-e 判斷對象是否存在(不管是目錄還是文件)

[root@svr5 ~]# [ -e "/usr/src/" ] && echo "存在" || echo "不存在"
存在
[root@svr5 ~]# [ -e "/etc/fstab" ] && echo "存在" || echo "不存在"
存在
[root@svr5 ~]# [ -e "/home/nooby" ] && echo "存在" || echo "不存在"
不存在

2)-d 判斷對象是否爲目錄(存在且是目錄)

[root@svr5 ~]# [ -d "/usr/src/" ] && echo "是目錄" || echo "不是目錄"
是目錄
[root@svr5 ~]# [ -d "/etc/fstab" ] && echo "是目錄" || echo "不是目錄"
不是目錄
[root@svr5 ~]# [ -d "/home/nooby" ] && echo "是目錄" || echo "不是目錄"
不是目錄

3)-f 判斷對象是否爲文件(存在且是文件)

[root@svr5 ~]# [ -f "/usr/src/" ] && echo "是文件" || echo "不是文件"
不是文件
[root@svr5 ~]# [ -f "/etc/fstab" ] && echo "是文件" || echo "不是文件"
是文件
[root@svr5 ~]# [ -f "/home/nooby" ] && echo "是文件" || echo "不是文件"
不是文件

4)-r 判斷對象是否可讀

此測試對root用戶無效,無論文件是否設置r權限,root都可讀:

[root@svr5 ~]# cp install.log /tmp/rtest.txt      //複製一個文件做測試
[root@svr5 ~]# chmod -r /tmp/rtest.txt          //去掉所有的r權限
[root@svr5 ~]# ls -ld /tmp/rtest.txt              //確認設置結果
--w------- 1 root root 33139 12-11 10:43 /tmp/rtest.txt 
[root@svr5 ~]# [ -r "/tmp/rtest.txt" ] && echo "可讀" || echo "不可讀"
可讀                                              //root測試結果仍然可讀

切換爲普通用戶,再執行相同的測試,結果變爲“不可讀”:

[zengye@svr5 ~]$ [ -r "/tmp/rtest.txt" ] && echo "可讀" || echo "不可讀"
不可讀

普通用戶只對自己擁有r權限的文件或目錄,-r測試時結果才成立:

[zengye@svr5 ~]$ ls -l .bashrc
-rw-r--r-- 1 zengye zengye 124 09-24 16:44 .bashrc
[zengye@svr5 ~]$ [ -r ".bashrc" ] && echo "可讀" || echo "不可讀"
可讀

5)-w 判斷對象是否可寫

此測試同樣對root用戶無效,無論文件是否設置w權限,root都可寫:

[root@svr5 ~]# chmod -w /tmp/rtest.txt             //去掉所有的w權限
[root@svr5 ~]# ls -l /tmp/rtest.txt              //確認設置結果
---------- 1 root root 33139 12-11 10:43 /tmp/rtest.txt
[root@svr5 ~]# [ -w "/tmp/rtest.txt" ] && echo "可寫" || echo "不可寫"
可寫

切換爲普通用戶,可以正常使用-w測試:

[zengye@svr5 ~]$ ls -l /tmp/rtest.txt
---------- 1 root root 33139 12-11 10:52 /tmp/rtest.txt
[zengye@svr5 ~]$ [ -w "/tmp/rtest.txt" ] && echo "可寫" || echo "不可寫"
不可寫
[zengye@svr5 ~]$ ls -l .bashrc
-rw-r--r-- 1 zengye zengye 124 09-24 16:44 .bashrc
[zengye@svr5 ~]$ [ -w ".bashrc" ] && echo "可寫" || echo "不可寫"
可寫

6)-x 判斷對象是否具有可執行權限

這個取決於文件本身、文件系統級的控制,root或普通用戶都適用:

[root@svr5 ~]# chmod 644 /tmp/rtest.txt          //重設權限,無x
[root@svr5 ~]# ls -l /tmp/rtest.txt              //確認設置結果
-rw-r--r-- 1 root root 33139 12-11 10:52 /tmp/rtest.txt
[root@svr5 ~]# [ -x "/tmp/rtest.txt" ] && echo "可執行" || echo "不可執行"
不可執行
[root@svr5 ~]# chmod +x /tmp/rtest.txt          //添加x權限
[root@svr5 ~]# [ -x "/tmp/rtest.txt" ] && echo "可執行" || echo "不可執行"
可執行

步驟五:多個條件/操作的邏輯組合

1)&&,邏輯與

給定條件必須都成立,整個測試結果才爲真。

檢查變量X的值是否大於10,且小於30:

[root@svr5 ~]# X=20                      //設置X變量的值爲20
[root@svr5 ~]# [ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES"
YES

多個條件組合時,可以使用 [[ .. ]] 界定,比如上述測試可以改爲如下:

[root@svr5 ~]# [[ $X -gt 10 && $X -lt 30 ]] && echo "YES"
YES

2)||,邏輯或

只要其中一個條件成立,則整個測試結果爲真。

檢查變量X的值是否小於10或者小於30:

[root@svr5 ~]# [[ $X -lt 10 || $X -lt 30 ]] && echo "YES"
YES

只要/tmp/、/var/spool/目錄中有一個可寫,則條件成立:

[root@svr5 ~]# [ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK"
OK

3 案例3:使用if選擇結構
3.1 問題

本案例要求編寫3個Shell腳本,分別實現以下目標:

檢測/media/cdrom目錄,若不存在則創建
檢測並判斷指定的主機是否可ping通
從鍵盤讀取一個論壇積分,判斷論壇用戶等級,等級分類如下:

大於等於90 神功絕世

大於等於80,小於90 登峯造極

大於等於70,小於80 爐火純青

大於等於60,小於70 略有小成

大於60 初學乍練
3.2 方案

if單分支的語法組成:

if  條件測試
    then  命令序列
fi  

if雙分支的語法組成:

if  條件測試
    then  命令序列1
    else  命令序列2
fi

if多分支的語法組成:

if  條件測試1
    then  命令序列1
elif  條件測試2
    then  命令序列2
    else  命令序列n
fi

if多分支結構實際上相當於多層if嵌套:

if  條件測試1  ; then
    命令序列1
else
    if  條件測試2  ; then
        命令序列2
    else
        .. ..
        命令序列n
    fi
fi

3.3 步驟

實現此案例需要按照如下步驟進行。

步驟一:檢測/media/cdrom目錄,若不存在則創建

1)編寫腳本如下:

[root@svr5 ~]# vim chkmountdir.sh 
#!/bin/bash
MOUNT_DIR="/media/cdrom/"
if [ ! -d $MOUNT_DIR ]
then
    mkdir -p $MOUNT_DIR
fi 
[root@svr5 ~]# chmod +x chkmountdir.sh                  //添加可執行權限

2)測試、驗證腳本功能

[root@svr5 ~]# ls -ld /media/cdrom                  //本來沒有/media/cdrom目錄
ls: /media/cdrom: 沒有那個文件或目錄
[root@svr5 ~]# ./chkmountdir.sh                      //執行腳本
[root@svr5 ~]# ls -ld /media/cdrom                  //再檢查已經有了
drwxr-xr-x 2 root root 4096 12-11 15:16 /media/cdrom

有了/media/cdrom文件夾以後,再次執行上述腳本,實際上不做任何有效操作:

[root@svr5 ~]# ./chk_bakdir.sh
[root@svr5 ~]#

步驟二:檢測並判斷指定的主機是否可ping通

1)分析任務需求

使用ping命令檢測目標主機時,人工可直接判斷反饋結果,而腳本卻不方便。但是當ping測試成功時,執行狀態$?的值爲0;而ping測試失敗時,$?的值不爲0。因此在Shell腳本中可以利用這一點來判斷ping目標主機的成敗。

爲了節省ping測試時間,可以只發送3個測試包(-c 3)、縮短髮送測試包的間隔秒數(-i 0.2)、等待反饋的超時秒數【-W(timeout) 3】。比如,檢查可ping通的主機:

[root@svr5 ~]# ping -c 3 -i 0.2 -W 3 192.168.4.5
PING 192.168.4.5 (192.168.4.5) 56(84) bytes of data.
64 bytes from 192.168.4.5: icmp_seq=1 ttl=64 time=0.131 ms
64 bytes from 192.168.4.5: icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from 192.168.4.5: icmp_seq=3 ttl=64 time=0.073 ms
--- 192.168.4.5 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 402ms
rtt min/avg/max/mdev = 0.073/0.093/0.131/0.027 ms
[root@svr5 ~]# echo $?                                  //執行狀態表示成功
0

2)腳本編寫參考如下:

[root@svr5 ~]# vim pinghost.sh 
#!/bin/bash
ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
if [ $? -eq 0 ] ; then
    echo "Host $1 is up."
else
    echo "Host $1 is down."
fi
[root@svr5 ~]# chmod +x pinghost.sh 

3)測試、驗證腳本功能

[root@svr5 ~]# ./pinghost.sh 192.168.4.5
Host 192.168.4.5 is up.
[root@svr5 ~]# ./pinghost.sh 192.168.4.50
Host 192.168.4.50 is down.

步驟三:從鍵盤讀取一個論壇積分,判斷論壇用戶等級

1)腳本編寫參考如下:

大於等於90 神功絕世

大於等於80,小於90 登峯造極

大於等於70,小於80 爐火純青

大於等於60,小於70 略有小成

大於60 初學乍練

[root@svr5 ~]# vim gradediv.sh 
#!/bin/bash
read -p "請輸入積分(0-100):" JF
if [ $JF –ge 90 ] ; then
    echo "$JF 分,神功絕世"
elif [ $JF –ge 80 ] ; then
    echo "$JF 分,登峯造極"
elif [ $JF –ge 70 ] ; then
    echo "$JF 分,爐火純青"
elif [ $JF –ge 60 ] ; then
    echo "$JF 分,略有小成"
else
    echo "$JF 分,初學乍練"
fi
[root@svr5 ~]# chmod +x gradediv.sh

2)測試、驗證腳本

[root@svr5 ~]# ./gradediv.sh 
請輸入積分(0-100):74
74 分,爐火純青
[root@svr5 ~]# ./gradediv.sh 
請輸入分數(0-100):68
68 分,略有小成
[root@svr5 ~]# ./gradediv.sh 
請輸入分數(0-100):87
87 分,登峯
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章