使shell用结构化命令
生活随笔
收集整理的這篇文章主要介紹了
使shell用结构化命令
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
shell--使用結(jié)構(gòu)化命令
使用結(jié)構(gòu)化命令知識(shí)內(nèi)容:
# 改變命令流
# 使用if-then邏輯
# 嵌套if-then
# 測(cè)試條件
# 高級(jí)if-then功能
許多程序在腳本命令之間需要某些邏輯控制流,有些命令允許腳本根據(jù)變量值的條件或者命令的結(jié)果跳過一些命令或者循環(huán)
執(zhí)行這些命令,這叫做結(jié)構(gòu)化命令。
1、使用if-then語句
最基本的結(jié)構(gòu)化命令類型就是if-then語句,其格式如下:
if command
then
? ? ? ? command
fi
意思是說:if語句后面的命令的退出狀態(tài)值是0,則執(zhí)行then后面的所有命令;如果不是0則命令不執(zhí)行。如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
if date
then
? ?? ???echo "it works"
fi
[root@wzp ~]# ./test2
2011年 01月 28日 星期五 21:15:12 CST
it works
我們知道date命令是有效命令,查看$?肯定是0的,所以就執(zhí)行then后的命令,這個(gè)應(yīng)該不難理解。
2、if-then-else語句
這個(gè)語句可以提供一組命令,其格式如下:
if command
then
? ? ? ? command
else
? ? ? ? command
if
意思是說:if語句后面的命令的退出狀態(tài)值是0,則執(zhí)行then后面的所有命令;跟if-then一樣,如果不是則執(zhí)行else后面的
命令。如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
testuser=51cto
if grep $testuser /etc/passwd
then
? ?? ???echo??the files for $testuser are:
? ?? ???ls -a /home/$testuser/.*
else
? ?? ???echo the user name $testuser does not exist !
fi
[root@wzp ~]# ./test2
the user name 51cto does not exist !
從上面可以看到由于不存在51cto用戶,則執(zhí)行else后面的命令
但是當(dāng)我創(chuàng)建了51cto用戶,則:
[root@wzp ~]# useradd 51cto
[root@wzp ~]# ./test2
51cto:x:502:502::/home/51cto:/bin/bash
the files for 51cto are:
/home/51cto/.bash_logout? ?/home/51cto/.bashrc
/home/51cto/.bash_profile??/home/51cto/.emacs
/home/51cto/.:
.??..??.bash_logout??.bash_profile??.bashrc??.emacs??.mozilla
/home/51cto/..:
.??..??51cto??aa??bb??lost+found
/home/51cto/.mozilla:
.??..??extensions??plugins
直接執(zhí)行then后的命令!這個(gè)也容易理解!~
3、嵌套if語句
有時(shí)需要在腳本代碼中檢查幾種情況,可以使用else的另一種版本叫elif,但是要嵌套許多if-then語句,后續(xù)有case命令介
紹,這個(gè)更加的方便使用,這里就不對(duì)嵌套if語句詳解了,其格式是:
if command
then
? ? ? ? command
elif? ? command
then
? ?
command
fi
4、test命令
這是一個(gè)重頭戲,bash shell提供一種在if-then語句中聲明test命令的另一種方法:
if [ condition ]??//注意這里的condition兩邊有空格!切記!
then
? ? ? ? command
fi
test命令能夠評(píng)估以下3類命令:
# 數(shù)值比較
# 字符串比較
# 文件比較
下面就具體就test命令的用戶逐一說明!!!
4.1、數(shù)值比較
如下式數(shù)值比較表:
**********************************************
n1??-eq??n2? ? 檢查n1是不是等于n2
n1??-ge??n2? ? 檢查n1是不是大于或等于n2
n1??-gt??n2? ? 檢查n1是否大于n2
n1??-le??n2? ? 檢查n1是否小于或等于n2
n1??-lt??n2? ? 檢查n1是否小于n2
n1??-ne??n2? ? 檢查n1是否不等于n2
**********************************************
下面看看一個(gè)例子:
[root@wzp ~]# cat test2
#!/bin/bash
num1=10
num2=11
if [ $num1 -gt 5 ]
then
??echo the test value $num1 is greater than 5
fi
if [ $num2 -eq $num1 ]
then
??echo??the values are equal
else
??echo??the values are different
fi
[root@wzp ~]# ./test2
the test value 10 is greater than 5
the values are different
給num1和num2賦值,然后通過測(cè)試,得出不同結(jié)論,這個(gè)好理解!
4.2、字符串比較
test命令允許對(duì)字符串值進(jìn)行比較,主要分為如下三種比較類型:
1、字符串是否相同
2、字符串順序(大小)
3、字符串長(zhǎng)度
首先也先看看test命令字符串比較表
********************************************
str1 = str2? ?檢查str1和str2是否相同
str1 != str2??檢查str1和str2是否不同
str1 < str2? ?檢查str1是否小于str2
str1 > str2? ?檢查str1是否大于str2
??-n str1? ???檢查str1長(zhǎng)度是否大于0
??-z str1? ???檢查str1長(zhǎng)度是否為0
********************************************
下面對(duì)三種類型舉個(gè)例子:
1)字符串是否相等
[root@wzp ~]# cat test2
#!/bin/bash
testuser=root
if [ $USER = $testuser ]
then
??echo welcome $testuser
fi
[root@wzp ~]# ./test2
welcome root
可以看到字符串相等的顯示效果
[root@wzp ~]# cat test2
#!/bin/bash
testuser=root
if [ $USER != $testuser ]
then
??echo this is not $testuser
else
??echo welcome $testuser
fi
[root@wzp ~]# ./test2
welcome root
不相等的情況則顯示else后的內(nèi)容
2)字符串順序
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=bbb
if [ $str1 > $str2 ]
then
??echo $str1 is greater than $str2
else
??echo $str1 is less than $str2
fi
[root@wzp ~]# ./test2
aaa is greater than bbb
[root@wzp ~]# ll aaa
-rw-r--r-- 1 root root 0 01-28 22:22 aaa
在腳本中單獨(dú)使用了大于號(hào)>,雖然沒報(bào)錯(cuò),但結(jié)果是錯(cuò)誤的,a打頭肯定是小于b的。這個(gè)腳本把大于號(hào)理解成輸出重定向,
所以才出現(xiàn)這樣的情況,我們可以通過轉(zhuǎn)義大于號(hào)解決這個(gè)問題:
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=bbb
if [ $str1 \> $str2 ]? ???//此處添加一個(gè)\就行了
then
??echo $str1 is greater than $str2
else
??echo $str1 is less than $str2
fi
[root@wzp ~]# ./test2
aaa is less than bbb
這樣就得出了正確的結(jié)果!
還有一點(diǎn)要說明的就是大小寫的問題,它的順序跟sort命令的順序是相反的!test命令是通過ASCII數(shù)值來決定排列順序的,
這個(gè)稍微了解下就好。
3)字符串大小
評(píng)估一個(gè)變量是否包含數(shù)據(jù),通過使用-n和-z比較很方便,如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=
if [ -n $str1 ]? ? //長(zhǎng)度是否大于0
then
? ?? ???echo the string $str1 is not empty
else
? ?? ???echo the string $str1 is empty
fi
if [ -z $str2 ]? ???//長(zhǎng)度是否為0
then
? ?? ???echo the string $str2 is empty
else
? ?? ???echo the string $str2 is not empty
fi
if [ -z $str3 ]? ???//長(zhǎng)度是否為0
then
? ?? ???echo the string $str3 is empty
else
? ?? ???echo the string $str3 is not empty
fi
[root@wzp ~]# ./test2
the string aaa is not empty
the string is empty
the string is empty
如上對(duì)于str1和str2應(yīng)該沒什么問題,而對(duì)于沒有定義變量str3則認(rèn)定其字符串為零。
4.3、文件比較
test命令能夠檢測(cè)linux文件系統(tǒng)上的文件狀態(tài)和路徑,對(duì)于文件比較這一塊挺多東西的,下面一一道來,首先看看test命令
文件比較表:
****************************************************************
-d file
檢測(cè)file是否存在并且是一個(gè)目錄
-e file
檢測(cè)file是否存在
-f file
檢測(cè)file是否存在并且是一個(gè)文件
-r file
檢測(cè)file是否存在并且刻度
-s file
檢測(cè)file是否存在并且不為空
-w file
檢測(cè)file是否存在并且可寫
-x file
檢測(cè)file是否存在并且可執(zhí)行
-O file
檢測(cè)file是否存在并且被當(dāng)前用戶擁有
-G file
? ?? ???檢測(cè)file是否存在并且默認(rèn)組是否為當(dāng)前用戶組
file1 -nt file2
檢測(cè)file1是否比file2新
file1 -ot file2
檢測(cè)file1是否比file2舊
*****************************************************************
對(duì)于上面這個(gè)表,如下通過10個(gè)例子說明:
1)檢測(cè)目錄
[root@wzp ~]# cat test2
#!/bin/bash
if [ -d $HOME ]
then
??echo your home directory exists
??cd $HOME
??ls
else
??echo there is someting wrong with your HD
fi
[root@wzp ~]# ./test2
your home directory exists
aaa? ?? ?? ?? ???bbb? ?? ?install.log? ?? ?? ?mbox??test2
anaconda-ks.cfg??Desktop??install.log.syslog??one
使用-d把我這個(gè)root的家目錄ls出來了~~
2)檢測(cè)對(duì)象是否存在
[root@wzp ~]# cat test2
#!/bin/bash
if [ -e $HOME ]
then
??echo? ?yes, the HD exists
??if [ -e $HOME/bbs.51cto ]
??then
? ? echo the bbs.51cto exists
??else
? ? touch $HOME/bbs.51cto
? ? echo creating new file name bbs.51cto
??fi
fi
從上面我們看到目錄肯定是存在的,我的root嘛,但是這個(gè)bbs.51cto是不存在的,所以第一次執(zhí)行文件顯示不存在,并且私
下創(chuàng)建了。
[root@wzp ~]# ./test2
yes, the HD exists
creating new file name bbs.51cto
第二次執(zhí)行文件那肯定是顯示存在bbs.51cto了,呵呵
[root@wzp ~]# ./test2
yes, the HD exists
the bbs.51cto exists
3)檢測(cè)文件
-e適合用于檢測(cè)文件和目錄,要確定對(duì)象是文件,使用-f比較,下例:
[root@wzp ~]# cat test2
#!/bin/bash
if [ -e $HOME ]
then
??echo the $HOME exists !
??if [ -f $HOME ]
??then
? ? echo yes, it is a file
??else
? ? echo no, it is not a file
? ?? ???if [ -f $HOME/.bash_history ]
? ?? ???then
? ?? ?? ? echo but $HOME/.bash_history is a file
? ?? ???else
? ?? ?? ? echo it is not a file too
? ?? ???fi
??fi
else
??echo there is not object!
fi
[root@wzp ~]# ./test2
the /root exists !
no, it is not a file
but /root/.bash_history is a file
上面的例子應(yīng)該很好懂,注意-f是檢測(cè)文件,-e可以檢測(cè)文件和目錄就行了!
4)檢測(cè)是否可讀
通過-r可檢測(cè)可讀性,如下例:
[51cto@wzp ~]$ whoami
51cto
[51cto@wzp ~]$ cat test
#!/bin/bash
testfile=/etc/shadow
if [ -f $testfile ]
then
??if [ -r $testfile ]
??then
? ? ls -l $testfile
??else
? ? echo "i'm unable to read the file"
??fi
else
??echo "the file doesn't exist"
fi
[51cto@wzp ~]$ sh test
i'm unable to read the file
[51cto@wzp ~]$ su - root
口令:
[root@wzp ~]# sh /home/51cto/test
-r-------- 1 root root 1204 01-28 21:27 /etc/shadow
如上可知普通用戶51cto無法讀取文件。
5)檢測(cè)空文件
通過-s檢測(cè)文件是否不為空,例子如下:
[root@wzp ~]# cat test2
#!/bin/bash
file=testfile
touch $file
if [ -s $file ]
then
??echo the file exists and has data in it
else
??echo the file exists but empty
fi
date > $file
if [ -s $file ]
then
??echo the file exists and has data in it
else
??echo the file exists but empty
fi
[root@wzp ~]# ./test2
the file exists but empty
the file exists and has data in it
先是創(chuàng)建空文件,然后通過重定向date進(jìn)去判斷文件不為空,這個(gè)好理解!
6)檢測(cè)是否能夠可寫
通過-w檢測(cè)文件是否可寫,例子如下:
[root@wzp ~]# cat test2
#!/bin/bash
file=$HOME/testfile
touch $file
chmod u-w $file
now='date +%y%m%d-%H%M'
if [ -w $file ]
then
??echo the file could be written
else
??echo "the file couldn't be written"
fi
chmod u+w $file
if [ -w $file ]
then
??echo the file could be written
??$now > $HOME/testfile
??echo??and the file views $file
else
??echo "the file couldn't be written"
fi
[root@wzp ~]# ./test2
the file could be written
the file could be written
and the file views /root/testfile
[root@wzp ~]# cat /root/testfile
110129-1317
上面的例子好理解,沒什么好說的。
7)檢測(cè)是否能運(yùn)行文件
通過-x可以檢測(cè)文件是否可被執(zhí)行,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=$HOME/testfile2
touch $file
chmod u+x $file
if [ -x $file ]
then
??echo the file could be run
else
??echo "the file couldn't be run"
fi
[root@wzp ~]# ./test2
the file could be run
[root@wzp ~]# ll testfile2
-rwxr--r-- 1 root root 0 01-29 13:21 testfile2
這個(gè)也沒什么疑惑之處。
8)檢測(cè)所有者
通過-O可以檢測(cè)你是否屬于這個(gè)文件的所有者,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=/etc/passwd
if [ -O $file ]
then
??echo "you are the owner of the $file"
else
??echo "you aren't the owner of the $file"
fi
[root@wzp ~]# ./test2
you are the owner of the /etc/passwd
[root@wzp ~]# ll /etc/passwd
-rw-r--r-- 1 root root 1877 01-28 21:27 /etc/passwd
/etc/passwd屬有者肯定是root啦!
9)檢測(cè)所屬組
-G檢測(cè)文件的默認(rèn)組,如果它跟當(dāng)前用戶的默認(rèn)組匹配,則檢測(cè)成功,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=/etc/passwd
if [ -G $file ]
then
??echo "you are in the same group as $file"
else
??echo "you aren't in the same group as the $file"
fi
[root@wzp ~]# ./test2
you are in the same group as /etc/passwd
[root@wzp ~]# ll -d /etc/passwd
-rw-r--r-- 1 root root 1877 01-28 21:27 /etc/passwd
很明顯,/etc/passwd肯定屬于root組咯
[root@wzp ~]# chgrp 51cto /etc/passwd
[root@wzp ~]# ll -d /etc/passwd
-rw-r--r-- 1 root 51cto 1877 01-28 21:27 /etc/passwd
[root@wzp ~]# ./test2
you aren't in the same group as the /etc/passwd
當(dāng)把這個(gè)文件的所屬組改成51cto后,則檢測(cè)不成功了,不過現(xiàn)實(shí)中別做這樣的修改
10)檢測(cè)文件日期
一般通過-nt和-ot來比較兩個(gè)文件之間的新舊,這里指的是創(chuàng)建或修改日期,例子:
[root@wzp ~]# ll aa bb
-rw-r--r-- 1 root root 0 01-29 13:41 aa
-rw-r--r-- 1 root root 0 01-29 14:23 bb
[root@wzp ~]# cat test2
#!/bin/bash
if [ $HOME/aa -nt $HOME/bb ]
then
??echo the aa is newer than bb
else
??echo the aa is older than bb
fi
[root@wzp ~]# ./test2
the aa is older than bb
下面我把a(bǔ)a文件修改下內(nèi)容:
[root@wzp ~]# vim aa
[root@wzp ~]# ll aa bb
-rw-r--r-- 1 root root 3 01-29 14:28 aa
-rw-r--r-- 1 root root 0 01-29 14:23 bb
[root@wzp ~]# ./test2
the aa is newer than bb
這個(gè)結(jié)果應(yīng)該很容易接受!
OKOK,到這里test命令的內(nèi)容就結(jié)束了,如上各種類型比較得以說明了。
5、復(fù)合條件檢測(cè)
if-then語句可以使用布爾邏輯來合并檢測(cè)條件,格式:
*****************************************************
[ condition ] && [ condition ]? ?這個(gè)表示邏輯與 and
[ condition ] || [ condition ]? ?這個(gè)表示邏輯或 or
*****************************************************
如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/wzp ]
then
??echo the file exists and you can wirte $HOME/wzp
else
??echo "you can't write the file"
fi
if [ -d $HOME ] || [ -w $HOME/wzp ]
then
??echo the file exists and you can wirte $HOME/wzp
else
??echo "you can't write the file"
fi
[root@wzp ~]# ./test2
you can't write the file
the file exists and you can wirte /root/wzp
[root@wzp ~]# ll /root/wzp
ls: /root/wzp: 沒有那個(gè)文件或目錄
$HOME是root家目錄,肯定存在的,但是不存在文件/root/wzp
6、if-then的高級(jí)特征
既然說是高級(jí)特征,必然作用非凡了,呵呵
其功能體現(xiàn)是通過雙圓括號(hào)(())表示數(shù)學(xué)表達(dá)式和雙方括號(hào)[[]]表示高級(jí)字符串處理函數(shù)。
6.1、使用雙圓括號(hào)
先看一個(gè)例子:
[root@wzp ~]# cat test2
#!/bin/bash
num1=10
if (( $num1 ** 2 > 90 ))
then
??(( num2=$num1 ** 2 ))
??echo the square of $num1 is $num2
fi
[root@wzp ~]# ./test2
the square of 10 is 100
這里的**表示取冪,由此可見(())可以很方便處理數(shù)學(xué)表達(dá)式
6.2、使用雙方括號(hào)
使用雙方括號(hào)可以定義與字符串值相匹配的正則表達(dá)式,如例:
[root@wzp ~]# cat test2
#!/bin/bash
if [[ $USER == r* ]]
then
??echo??hello $USER
else
??echo sorry , i "don't" know you
fi
[root@wzp ~]# ./test2
hello root
[root@wzp ~]# cp test2 /home/51cto/
[root@wzp ~]# su - 51cto
[51cto@wzp ~]$ sh test2
sorry , i don't know you
這里用到了通配符*,表示r開頭的任何用戶,正則表達(dá)式的內(nèi)容放置后面說明!
[root@wzp ~]# useradd rrr
[root@wzp ~]# cp test2 /home/rrr
[root@wzp ~]# su - rrr
[rrr@wzp ~]$ sh test2
hello rrr
這都好理解吧~~~
7、case命令
還記得前面提及到case命令吧,當(dāng)在一組可能的值中尋找特定的值,可以寫if-then-else語句,其中嵌套elif語句繼續(xù)著if
-then檢測(cè),這樣子就很冗長(zhǎng)麻煩。所以可以通過case命令簡(jiǎn)化,以列表導(dǎo)向格式檢測(cè)單個(gè)變量的多個(gè)值,格式為:
case xxx in
xx | xx) command;;
xx) command;;
*) default command;;
esac
下面通過一個(gè)例子:
[root@wzp ~]# cat test2
#!/bin/bash
case $USER in
root | testuser)
echo welcome $USER
echo you are admin;;
51cto)
echo welcome $USER;;
*)
echo welcome $USER;;
esac
[root@wzp ~]# ./test2
welcome root
you are admin
[root@wzp ~]# cp test2 /home/51cto/
cp:是否覆蓋“/home/51cto/test2”? y
[root@wzp ~]# su - 51cto
[51cto@wzp ~]$ sh test2
welcome 51cto
判斷是root和51cto用戶則顯示特定內(nèi)容,如果通過其他用戶執(zhí)行,如下:
[root@wzp ~]# useradd testuser24
[root@wzp ~]# cp test2 /home/testuser24/
[root@wzp ~]# su - testuser24
[testuser24@wzp ~]$ sh test2
welcome testuser24
這個(gè)都比較好理解吧,假設(shè)通過存在的用戶testuser執(zhí)行,那顯示的內(nèi)容肯定是:
welcome testuser
your are admin
哈哈,說是admin也不正確了。
好了,對(duì)于部分結(jié)構(gòu)化命令就說到這里,后續(xù)是循環(huán)、迭代等結(jié)構(gòu)化命令的講述。
轉(zhuǎn)載于:https://blog.51cto.com/2942350/557914
總結(jié)
以上是生活随笔為你收集整理的使shell用结构化命令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用WCF上传文件
- 下一篇: 30款非常酷的创意名片设计欣赏