當(dāng)前位置:首頁 > IT技術(shù) > 系統(tǒng)服務(wù) > 正文

【shell】if常用判斷|if目錄是否為空|判斷字符串包含關(guān)系|與或shell中[ ]和[[]]的區(qū)別
2021-09-28 16:49:02

目錄

??shell中[ ]和[[]]的區(qū)別??

??判斷目錄是否為空??

??判斷字符串包含關(guān)系??

??if常用判斷??

??SHELL 與或表達(dá)??



shell中[ ]和[[]]的區(qū)別?

多數(shù)情況下[ ]和[[]]是可以通用的,單中括號 [ ],bash 的內(nèi)部命令,[和test是等同的。雙中括號[[ ]],[[是 bash 程序語言的關(guān)鍵字。并不是一個命令,[[ ]] 結(jié)構(gòu)比[ ]結(jié)構(gòu)更加通用。

[ ] 和 [[]]區(qū)別

[ ]中可用的比較運(yùn)算符只有==和!=,可用于字符串比較的,不可用于整數(shù)比較,整數(shù)比較只能使用-eq,-gt這種形式。

[[ ]] 支持字符串的模式匹配,使用=~操作符時甚至支持shell的正則表達(dá)式。字符串比較時可以把右邊的作為一個模式,而不僅僅是一個字符串,比如[[ minger == ming? ]],結(jié)果為真。[[ ]] 中匹配字符串或通配符,不需要引號。


?

[[]]測試

[]測試

< 排序比較

不支持

> 排序比較

不支持

&& 邏輯與

-a 邏輯與

== 模式匹配

==字符匹配

=~正則匹配

不支持

判斷目錄是否為空

ls?dirname

如果返回為空則目錄為空

或者ls?dirname|wc?-l

如果結(jié)果為0則目錄為空 ? ? ? ??

最簡單的方法:用ls?-A??$dir

好用的,測試過,對.file也能好用。

#!/bin/sh

#ifdirec

DIRECTORY=$1

#在此加上是不是目錄的判斷。

if [ "`ls -A $DIRECTORY`" = "" ]; then

echo "$DIRECTORY is indeed empty"

else

echo "$DIRECTORY is not empty"

fi

?

#判斷文件目錄是否為空

第一種:

emptydir.sh

-----------------------------------------------------------

#!/bin/sh
DIRECTORY=$1
if [ "`ls -A $DIRECTORY`" = "" ]; then
echo "$DIRECTORY is indeed empty"
else
echo "$DIRECTORY is not empty"
fi

-----------------------------------------------------------

第二種:

count.sh

-----------------------------------------------------------

#!/bin/sh
count=`ls $*|wc -w`
if [ "$count" > "0" ];
then
echo "file size $count"
else
echo "empty!"
fi

-----------------------------------------------------------

#目錄是否存在

ifmkdir.sh

-----------------------------------------------------------

#!/bin/sh
dir="test"
if [ ! -d $dir ]; then
echo "$dir not exists"
mkdir "$dir"
else
echo "$dir exists!"
fi

-----------------------------------------------------------

判斷字符串包含關(guān)系

??https://www.jb51.net/article/100490.htm??

方法一:利用grep查找


1

2

3

4

5

6

7

8

9



??strA=????"long string"??

??strB=????"string"??

??result=$(????echo?? ??$strA | ????grep?? ??"${strB}"????)??

??if?? ??[[ ????"$result"?? ??!= ????""?? ??]]??

??then??

??echo?? ??"包含"??

??else??

??echo?? ??"不包含"??

??fi??


先打印長字符串,然后在長字符串中 grep 查找要搜索的字符串,用變量result記錄結(jié)果

如果結(jié)果不為空,說明strA包含strB。如果結(jié)果為空,說明不包含。

這個方法充分利用了grep 的特性,最為簡潔。

方法二:利用字符串運(yùn)算符


1

2

3

4

5

6

7

8



??strA=????"helloworld"??

??strB=????"low"??

??if?? ??[[ $strA =~ $strB ]]??

??then??

??echo?? ??"包含"??

??else??

??echo?? ??"不包含"??

??fi??


利用字符串運(yùn)算符 =~ 直接判斷strA是否包含strB。(這不是比第一個方法還要簡潔嗎!)

方法三:利用通配符


1

2

3

4

5

6

7

8



??A=????"helloworld"??

??B=????"low"??

??if?? ??[[ $A == *$B* ]]??

??then??

??echo?? ??"包含"??

??else??

??echo?? ??"不包含"??

??fi??


這個也很easy,用通配符*號代理strA中非strB的部分,如果結(jié)果相等說明包含,反之不包含。

方法四:利用case in 語句


1

2

3

4

5

6



??thisString=????"1 2 3 4 5"?? ??# 源字符串??

??searchString=????"1 2"?? ??# 搜索字符串??

??case?? ??$thisString ????in??

??*????"$searchString"????*) ????echo?? ??Enemy Spot ;;??

??*) ????echo?? ??nope ;;??

??esa??


這個就比較復(fù)雜了,case in 我還沒有接觸到,不過既然有比較簡單的方法何必如此

方法五:利用替換


1

2

3

4

5

6

7

8

9

10

11

12



??STRING_A=$1??

??STRING_B=$2??

??if?? ??[[ ${STRING_A/${STRING_B}????//????} == $STRING_A ]]??

??then??

??## is not substring.??

??echo?? ??N??

??return?? ??0??

??else??

??## is substring.??

??echo?? ??Y??

??return?? ??1??

??fi??


這個也挺復(fù)雜

單引號和雙引號的區(qū)別

單引號字符串的限制:

  • 單引號里的任何字符都會原樣輸出,單引號字符串中的變量是無效的;
  • 單引號字串中不能出現(xiàn)單獨(dú)一個的單引號(對單引號使用轉(zhuǎn)義符后也不行),但可成對出現(xiàn),作為字符串拼接使用。

雙引號的優(yōu)點(diǎn):

  • 雙引號里可以有變量
  • 雙引號里可以出現(xiàn)轉(zhuǎn)義字符

?

if常用判斷

注意[] 后面是否需要加 “;”

文件表達(dá)式?

if [ -f file ]; 如果文件存在

if [ -d ... ]; 如果目錄存在

if [ -s file ]; 如果文件存在且非空 if [ -r file ] 如果文件存在且可讀 if [ -w file ] ?如果文件存在且可寫 if [ -x file ] 如果文件存在且可執(zhí)行?

整數(shù)變量表達(dá)式?

if [ int1 -eq int2 ] 如果int1等于int2?

if [ int1 -ne int2 ] 如果不等于 ?if [ int1 -ge int2 ] 如果>= if [ int1 -gt int2 ] 如果> if [ int1 -le int2 ] 如果<= if [ int1 -lt int2 ]如果<

?

字符串變量表達(dá)式?

If [ $a = $b ] ? 如果string1等于string2 字符串允許使用賦值號做等號

if [ $string1 != $string2 ] 如果string1不等于string2

if [ -n $string ] ? ? ? 如果string 非空(非0),返回0(true)

?if [ -z $string ] 如果string 為空

if [ $sting ] ? ? ? ? ? 如果string 非空,返回0 (和-n類似) ??

條件表達(dá)式引用變量要帶$

if [ a = b ] ;then

echo equal else echo no equal

fi?

[macg@machome ~]$ sh test.sh input a: 5 input b: 5 no equal (等于表達(dá)式?jīng)]比較$a和$b,而是比較和a和b,自然a!=b)?

改正:

if [ $a = $b ] ;then

echo equal else echo no equa

l fi?

[macg@machome ~]$ sh test.sh input a: 5 input b: 5 equal?

前言:

? ? ? ?if list then?

? ? ? ? ? ?do something here?

? ? ? ?elif list then?

? ? ? ? ? ?do another thing here?

? ? ? ?else?

? ? ? ? ? do something else here?

? ? ? ?fi ?

? ?

EX1:

?#!/bin/sh

?SYSTEM=`uname -s` ? ?#獲取操作系統(tǒng)類型,我本地是linux

?if [ $SYSTEM = "Linux" ] ; then ? ? #如果是linux的話打印linux字符串

echo "Linux"?

?elif [ $SYSTEM = "FreeBSD" ] ; then ??

?echo "FreeBSD"?

?elif [ $SYSTEM = "Solaris" ] ; then?

?echo "Solaris"?

?else?

?echo "What?"?

?fi ? ? #ifend

基本上和其他腳本語言一樣。沒有太大區(qū)別。不過值得注意的是。[]里面的條件判斷。

1、字符串判斷

str1 = str2      當(dāng)兩個串有相同內(nèi)容、長度時為真?

str1 != str2     ?當(dāng)串str1和str2不等時為真?

-n str1       ?當(dāng)串的長度大于0時為真(串非空) ,記得str1是帶雙引號的,如:“$NAME"

-z str1       ?當(dāng)串的長度為0時為真(空串)?

str1        ? ?當(dāng)串str1為非空時為真

2、數(shù)字的判斷

int1 -eq int2    兩數(shù)相等為真?

int1 -ne int2    兩數(shù)不等為真?

int1 -gt int2    int1大于int2為真?

int1 -ge int2    int1大于等于int2為真?

int1 -lt int2    int1小于int2為真?

int1 -le int2    int1小于等于int2為真

3、文件的判斷

-r file     用戶可讀為真?

-w file     用戶可寫為真?

-x file     用戶可執(zhí)行為真?

-f file     文件為正規(guī)文件為真?

-d file     文件為目錄為真?

-c file     文件為字符特殊文件為真?

-b file     文件為塊特殊文件為真?

-s file     文件大小非0時為真?

-t file     當(dāng)文件描述符(默認(rèn)為1)指定的設(shè)備為終端時為真

4、復(fù)雜邏輯判斷

-a  ?     ?與?

-o       ?或?

!        非

結(jié)尾

語法雖然簡單,但是在SHELL里使用的時候,他的功能變得強(qiáng)大了。

=====================================================================

附 表:

[ -a FILE ] ?如果 FILE 存在則為真。 ?

?[ -b FILE ] ?如果 FILE 存在且是一個塊特殊文件則為真。 ?

?[ -c FILE ] ?如果 FILE 存在且是一個字特殊文件則為真。 ?

?[ -d FILE ] ?如果 FILE 存在且是一個目錄則為真。 ?

?[ -e FILE ] ?如果 FILE 存在則為真。 ?

?[ -f FILE ] ?如果 FILE 存在且是一個普通文件則為真。 ?

?[ -g FILE ] 如果 FILE 存在且已經(jīng)設(shè)置了SGID則為真。 [ -h FILE ] ?如果 FILE 存在且是一個符號連接則為真。 ?

?[ -k FILE ] ?如果 FILE 存在且已經(jīng)設(shè)置了粘制位則為真。 ?

?[ -p FILE ] ?如果 FILE 存在且是一個名字管道(F如果O)則為真。 ?

?[ -r FILE ] ?如果 FILE 存在且是可讀的則為真。 ?

?[ -s FILE ] ?如果 FILE 存在且大小不為0則為真。 ?

?[ -t FD ] ?如果文件描述符 FD 打開且指向一個終端則為真。 ?

?[ -u FILE ] ?如果 FILE 存在且設(shè)置了SUID (set user ID)則為真。 ?

?[ -w FILE ] ?如果 FILE 如果 FILE 存在且是可寫的則為真。 ?

?[ -x FILE ] ?如果 FILE 存在且是可執(zhí)行的則為真。 ?

?[ -O FILE ] ?如果 FILE 存在且屬有效用戶ID則為真。 ?

?[ -G FILE ] ?如果 FILE 存在且屬有效用戶組則為真。 ?

?[ -L FILE ] ?如果 FILE 存在且是一個符號連接則為真。 ?

?[ -N FILE ] ?如果 FILE 存在 and has been mod如果ied since it was last read則為真。 ?

?[ -S FILE ] ?如果 FILE 存在且是一個套接字則為真。 ?

?[ FILE1 -nt FILE2 ] ?如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not則為真。 ?

?[ FILE1 -ot FILE2 ] ?如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在則為真。 ?

?[ FILE1 -ef FILE2 ] ?如果 FILE1 和 FILE2 指向相同的設(shè)備和節(jié)點(diǎn)號則為真。 ?

?[ -o OPTIONNAME ] ?如果 shell選項(xiàng) “OPTIONNAME” 開啟則為真。 ?

?[ -z STRING ] ?“STRING” 的長度為零則為真。 ?

?[ -n STRING ] or [ STRING ] ?“STRING” 的長度為非零 non-zero則為真。 ?

?[ STRING1 == STRING2 ] ?如果2個字符串相同。 “=” may be used instead of “==” for strict POSIX compliance則為真。 ?

?[ STRING1 != STRING2 ] ?如果字符串不相等則為真。?

[ STRING1 < STRING2 ] ?如果 “STRING1” sorts before “STRING2” lexicographically in the current locale則為真。 ?

?[ STRING1 > STRING2 ] ?如果 “STRING1” sorts after “STRING2” lexicographically in the current locale則為真。 ?

?[ ARG1 OP ARG2 ] “OP” is one of -eq, -ne, -lt, -le, -gt or -ge. These arithmetic binary operators return true if “ARG1” is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to “ARG2”, respectively. “ARG1” and “ARG2” are integers.

#this file compiled with GBK (chinese)?

________________________

./source/script/create_db_script/readme.txt

set_auto_run.sh :設(shè)置自啟動

Create_station_db.sh: 建立場站級

Create_center_db.sh:建立集團(tuán)級

如果創(chuàng)建的表格是帶外鍵約束的,那么執(zhí)行新的sql腳本腳本時,可能需要手動刪除舊表(先刪完子表,才能刪父表)后,才能創(chuàng)建同名新表。

./source/script/create_db_script/sql/readme.txt

__________________________

這里是建表的SQL腳本

外面的create_xxxx_db 腳本會先創(chuàng)建schema,然后調(diào)用建表腳本,將表導(dǎo)入。如果哪個表需要修改結(jié)構(gòu),只需修改后的表結(jié)構(gòu)導(dǎo)出來,放到對應(yīng)文件夾內(nèi)即可。

這里用可視化工具mysql-front 導(dǎo)出sql 時遇到過一個問題,就是表帶有觸發(fā)器時,導(dǎo)出來的腳本有錯,執(zhí)行時報錯。用SQLyoy導(dǎo)出(注意把觸發(fā)器勾上,不然不會導(dǎo)出來)時就沒這個問題。

#----------------------------------------------shell 腳本的一些方法說明-------------------

1、.fun文件:在里面定義一些函數(shù),在.sh 腳本中 用 “." 加載后,直接調(diào)用里面的函數(shù),如 .db.fun, 可以帶參數(shù),函數(shù)中的 $1 、$2 ……表示接受的第一個,第二個……參數(shù),

如: create_station_db 20, create_station_db 函數(shù)內(nèi)的$1 就是接收參數(shù)20的。?

腳本中用到的語法方法:

1、加載統(tǒng)一配置的文件

GLOBAL_CFG_FILE= `find ./ |grep global_config.txt` :將global_config.txt的路徑賦值給GLOBAL_CFG_FILE,注意1、“`”符號不是單引號 2、. 被加載的文件不能是.sh文件

. {GLOBAL_CFG_FILE} #load cfg file ? ? ? ? ? ? ? ?:加載global_config.txt

如果報錯,且在當(dāng)前腳本文件找不到錯誤源,那可能是被加載的文件有錯誤(語法錯誤等)

2、${} 和$()?

${NAME} 和$NAME ?都是引用替換變量NAME替換的內(nèi)容,但是${}更好的限定了替換的范圍 不然${AB}C 用 $ABC 就容易產(chǎn)生歧義

$(find ./ |grep global_config.sh) 和 ?`find ./ |grep global_config.sh` 一樣的效果,都是執(zhí)行命令,但是%()在有些shell下不支持

3、sed -i '/#hwBegin/,/#hwEnd/d' reame.txt

sed -i '/#hwBegin/,/#hwEnd/d' ?就是將#hwBegin到#hwEnd之間內(nèi)容,包括#hwBegin和#hwEnd都刪除

4、echo " hello " > reame.txt 是將“hello”覆蓋reame.txt內(nèi)的內(nèi)容

? ?echo " hello " 》 reame.txt 是在reame.txt的末尾追加"hello"

5、shell中的if else 語句

注意if 、elif和"[" 之間要有空格,"["和文字之間也要留有空格

if [ ${SERVER_NAME} == ${HOPE_CLOUD_SERVER_NAME}]; then

cd center_collector

./center_collector &?

cd ..

elif [ ${SERVER_NAME} == ${HOPE_VIEW_SERVER_NAME}; then

cd station_collector

./station_collector &?

cd ..

else

fi

6、xml 的if

if(a==22)

?{

? ?return a;

?}

?else

?return b;

<xsl:choose>

?<xsl:when test="a=22">

?a

?</xsl:when>

?<xsl:otherwise>

?b

?</xsl:otherwise>

?</xsl:choose>

?

可以嵌套么:

?

<xsl:choose>?

?<xsl:when test="a=22">?

?

<xsl:choose>?

?<xsl:when test="a=22">?

?a?

?</xsl:when>?

?<xsl:otherwise>?

?b?

?</xsl:otherwise>?

?</xsl:choose>?

?

</xsl:when>?

?<xsl:otherwise>?

?b?

?</xsl:otherwise>?

?</xsl:choose> ?

7#執(zhí)行參數(shù)指定的文件夾下面(含子文件夾下面)的所有sql腳本

#execute_all_sql_script() $1:在哪個SCHEMA執(zhí)行sql $2:sql 腳本所在的文件夾

function execute_all_sql_script()

{

for sqlfile in `ls $2`?

#$2 為執(zhí)行腳本時后面跟的第2個參數(shù)

do

if [ -d $2'/'${sqlfile} ]; ?then

#如果是個子文件夾 則進(jìn)去 遞歸

execute_all_sql_script $2'/'${sqlfile} ?

else

? if [ "${sqlfile##*.}" = "sql" ]; then?

#判斷文件后綴名是否是sql,是就執(zhí)行

? ? mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD} $1 < $2/${sqlfile}

? ?fi

fi

done

}

8

如果只顯示所在目錄的路徑:

?find 目錄 -type d -name "查詢目錄名" -printf "%h "

?

如果同時顯示目錄名稱和所在目錄的路徑:

?find 目錄 -type d -name "查詢目錄名" -printf "%p %h "?

?

?find . -name *.txt -mtime +2 -exec rm {} ;

?

?在linux下-exec經(jīng)常和find一起使用,當(dāng)匹配到一些文件以后,希望對其進(jìn)行某些操作,這時就可以使用-exec選項(xiàng),一旦find命令匹配到了相應(yīng)的文件,就可以用-exec選項(xiàng)中的命令對其進(jìn)行操作(在有些操作系統(tǒng)中只允許-exec選項(xiàng)執(zhí)行諸如ls或ls -l這樣的命令),exec選項(xiàng)后面跟隨著所要執(zhí)行的命令,然后是一對兒{},一個空格和一個 ,最后是一個分號。舉個例子:查詢當(dāng)前目錄下2天以上的txt文件,然后刪除它們find . -name *.txt -mtime +2 -exec rm {} ;

{}代表的是由find找到的內(nèi)容,而-exec一直到“;”是關(guān)鍵字,代表find額外命令的開始(-exec)到結(jié)束(;),在這中間的就是find命令內(nèi)的額外命令。

二,shell語句的比較操作符?

1,整數(shù)比較?

規(guī)則說明:?

-eq ? ? ?等于 ? ? ? ? ? ? ? ? ?if [ "$a" -eq "$b" ]?

-ne ? ? ?不等于 ? ? ? ? ? ? ? ?if [ "$a" -ne "$b" ]?

-gt ? ? ?大于 ? ? ? ? ? ? ? ? ?if [ "$a" -gt "$b" ]?

-ge ? ? ?大于等于 ? ? ? ? ? ? ?if [ "$a" -ge "$b" ]?

-lt ? ? ?小于 ? ? ? ? ? ? ? ? ? ?if [ "$a" -lt "$b" ]?

-le ? ? ?小于等于 ? ? ? ? ? ? ? if [ "$a" -le "$b" ]?

< ? ? ? ?小于(需要雙括號) ? ? ? ? ? (( "$a"< "$b" ))?

<= ? ? ? 小于等于(...) ? ? ? ? ? ? ? ?(("$a" <= "$b" ))?

> ? ? ? ?大于(...) ? ? ? ? ? ? ? ? ? ?(("$a" > "$b" ))?

>= ? ? ? 大于等于(...) ? ? ? ? ? ? ? ?(("$a" >= "$b" ))?

PS:小數(shù)據(jù)比較可使用AWK?

??

示例代碼:?

[root@squid-2 script]# cat com1.sh?

a=$1?

b=$2?

if [ "$a" -eq "$b" ];then?

? ? ? ? ?echo"a = b true."?

elif [ ! "$a" -gt "$b" ];then?

? ? ? ? ?echo"a > b true."?

else echo "a < b true."?

fi?

[root@squid-2 script]#?

測試結(jié)果如下:?

[root@squid-2 script]# sh com1.sh 1 1?

a = b true.?

[root@squid-2 script]# sh com1.sh 1 2?

a > b true.?

[root@squid-2 script]# sh com1.sh 1 0?

a < b true.?

[root@squid-2 script]#?

2,字符串比較?

2.1,規(guī)范以及使用?

規(guī)則說明:?

= ? ? 等于 ? ? ? ? ? if [ "$a"= "$b" ]?

== ? ?與=等價?

!= ? ?不等于 ? ? ? ? if [ "$a" ="$b" ]?

< ? ? 小于,在ASCII字母中的順序:?

? ? ? if [[ "$a" < "$b" ]]?

? ? ? if [ "$a" < "$b" ] ? ? ? ? #需要對<進(jìn)行轉(zhuǎn)義?

> ? ? 大于?

-z ? ?字符串為null,即長度為0?

-n ? ?字符串不為null,即長度不為0?

SHELL 與或表達(dá)

邏輯與的表達(dá):

1)、if [ $xxx=a -a $xx=b ]

注:-a表示and的意思

2)、if [ $xxx=a ] && [? $xx=b ]

邏輯或的表達(dá):

1)、if [ $xxx=a -o $xx=b ]

注:-o表示or的意思

2)、if [ $xxx=a ] || [? $xx=b ]

??javascript:void(0)??

??shell 判斷文件夾或文件是否存在??

文件夾不存在則創(chuàng)建


1

2

3

4

5



??if?????[ ! -d?????"/data/"?????];????then??

??mkdir?????/data??

??else??

??echo?????"文件夾已經(jīng)存在"??

??fi??


文件存在則刪除


1

2

3

4

5



??if?????[ ! -f?????"/data/filename"?????];????then??

??echo?????"文件不存在"??

??else??

??rm?????-f?????/data/filename??

??fi??


判斷文件夾是否存在


1

2

3

4

5



??if?????[ -d?????"/data/"?????];????then??

??echo?????"文件夾存在"??

??else??

??echo?????"文件夾不存在"??

??fi??


判斷文件是否存在


1

2

3

4

5



??if?????[ -f?????"/data/filename"?????];????then??

??echo?????"文件存在"??

??else??

??echo?????"文件不存在"??

??fi??


文件比較符


1

2

3

4

5

6

7

8

9

10

11

12

13



??-e 判斷對象是否存在??

??-d 判斷對象是否存在,并且為目錄??

??-f 判斷對象是否存在,并且為常規(guī)文件??

??-L 判斷對象是否存在,并且為符號鏈接??

??-h 判斷對象是否存在,并且為軟鏈接??

??-s 判斷對象是否存在,并且長度不為0??

??-r 判斷對象是否存在,并且可讀??

??-w 判斷對象是否存在,并且可寫??

??-x 判斷對象是否存在,并且可執(zhí)行??

??-O 判斷對象是否存在,并且屬于當(dāng)前用戶??

??-G 判斷對象是否存在,并且屬于當(dāng)前用戶組??

??-nt 判斷file1是否比file2新? [?????"/data/file1"?????-nt?????"/data/file2"?????]??

??-ot 判斷file1是否比file2舊? [?????"/data/file1"?????-ot?????"/data/file2"?????]??


本文摘自 :https://blog.51cto.com/l

開通會員,享受整站包年服務(wù)立即開通 >