linux shell中if的各种判断
shell编程中使用到得if语句内判断参数
–b当file存在并且是块文件时返回真
-c当file存在并且是字符文件时返回真
-d当pathname存在并且是一个目录时返回真
-e当pathname指定的文件或目录存在时返回真
-f当file存在并且是正规文件时返回真
-g当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
-h当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
-k当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
-p当file存在并且是命令管道时返回为真
-r当由pathname指定的文件或目录存在并且可读时返回为真
-s当file存在文件大小大于0时返回真
-u当由pathname指定的文件或目录存在并且设置了SUID位时返回真
-w当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
-o当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIXShell里面比较字符写法:
-eq等于
-ne不等于
-gt大于
-lt小于
-le小于等于
-ge大于等于
-z空串
=两个字符相等
!=两个字符不等
-n非空串
更为详细的说明:
运算符描述示例
文件比较运算符
-efilename如果filename存在,则为真[-e/var/log/syslog]
-dfilename如果filename为目录,则为真[-d/tmp/mydir]
-ffilename如果filename为常规文件,则为真[-f/usr/bin/grep]
-Lfilename如果filename为符号链接,则为真[-L/usr/bin/grep]
-rfilename如果filename可读,则为真[-r/var/log/syslog]
-wfilename如果filename可写,则为真[-w/var/mytmp.txt]
-xfilename如果filename可执行,则为真[-L/usr/bin/grep]
filename1-ntfilename2如果filename1比filename2新,则为真[/tmp/install/etc/services-nt/etc/services]
filename1-otfilename2如果filename1比filename2旧,则为真[/boot/bzImage-otarch/i386/boot/bzImage]
字符串比较运算符(请注意引号的使用,这是防止空格扰乱代码的好方法)
-zstring如果string长度为零,则为真[-z$myvar]
-nstring
如果string长度非零,则为真[-n$myvar]
string1=string2如果string1与string2相同,则为真[$myvar=onetwothree]
string1!=string2如果string1与string2不同,则为真[$myvar!=onetwothree]
算术比较运算符
num1-eqnum2等于[3-eq$mynum]
num1-nenum2不等于[3-ne$mynum]
num1-ltnum2小于[3-lt$mynum]
num1-lenum2小于或等于[3-le$mynum]
num1-gtnum2大于[3-gt$mynum]
num1-genum2大于或等于[3-ge$mynum]
脚本示例:
#!/bin/bash #Thisscriptprintsamessageaboutyourweightifyougiveityour #weightinkilosandhightincentimeters. if[!$#==2];then echo"Usage:{GetProperty(Content)}weight_in_kiloslength_in_centimeters" exit fi weight="{GetProperty(Content)}" height="$2" idealweight=$[$height-110] if[$weight-le$idealweight];then echo"Youshouldeatabitmorefat." else echo"Youshouldeatabitmorefruit." fi #weight.sh70150 Youshouldeatabitmorefruit. #weight.sh7015033 Usage:./weight.shweight_in_kiloslength_in_centimeters
位置参数{GetProperty(Content)},$2,...,$N,$#代表了命令行的参数数量,{GetProperty(Content)}代表了脚本的名字,
第一个参数代表{GetProperty(Content)},第二个参数代表$2,以此类推,参数数量的总数存在$#中,上面的例子显示了怎么改变脚本,如果参数少于或者多余2个来打印出一条消息。
执行,并查看情况。
#bash-xtijian.sh60170
+weight=60
+height=170
+idealweight=60
+'['60-le60']'
+echo'Youshouldeatabitmorefat.'
Youshouldeatabitmorefat.
其中-x用来检查脚本的执行情况
if语句格式
if条件
then
Command
else
Command
fi别忘了这个结尾
if语句忘了结尾fi
test.sh:line14:syntaxerror:unexpectedendoffi
if的三种条件表达式
if
command
then
if
函数
then
命令执行成功,等于返回0(比如grep,找到匹配)
执行失败,返回非0(grep,没找到匹配)
if[expression_r_r_r]
then
表达式结果为真,则返回0,if把0值引向then
iftestexpression_r_r_r
then
表达式结果为假,则返回非0,if把非0值引向then
[]&&——快捷if
[-f"/etc/shadow"]&&echo"Thiscomputerusesshadowpasswors"
&&可以理解为then
如果左边的表达式为真则执行右边的语句
shell的if与c语言if的功能上的区别
shellifc语言if
0为真,走then
正好相反,非0走then
不支持整数变量直接if
必须:if[i–ne0]
但支持字符串变量直接if
if[str]如果字符串非0
支持变量直接if
if(i)
以command作为if条件
以多条command或者函数作为if条件
echo–n“input:”
readuser
if
多条指令,这些命令之间相当于“and”(与)
grep$user/etc/passwd>/tmp/null
who-u|grep$user
then上边的指令都执行成功,返回值$?为0,0为真,运行then
echo"$userhaslogged"
else指令执行失败,$?为1,运行else
echo"$userhasnotlogged"
fi
#shtest.sh
input:macg
macgpts/0May1515:55.2075(192.168.1.100)
macghaslogged
#shtest.sh
input:ddd
dddhasnotlogged
以函数作为if条件(函数就相当于command,函数的优点是其return值可以自定义)
if
以函数作为if条件,
getyn
then函数reture值0为真,走then
echo"youranswerisyes"
else函数return值非0为假,走else
echo"youranserisno"
fi
ifcommand等价于command+if$?
$vitestsh.sh #!/bin/sh if cat111-tmp.txt|grepting1 then echofound else echo"nofound" fi $vitestsh.sh #!/bin/sh cat111-tmp.txt|grepting1 if[$?-eq0] then echo$? echofound else echo$? echo"nofound" fi $shtestsh.sh nofound $shtestsh.sh 1 nofound $vi111-tmp.txt thatis222file thisting1is111file $shtestsh.sh thisting1is111file found $vi111-tmp.txt thatis222file thisting1is111file $shtestsh.sh thisting1is111file 0 found
以条件表达式作为if条件
传统if从句子——以条件表达式作为if条件
if[条件表达式]
then
command
command
command
else
command
command
fi
条件表达式
文件表达式
if[-ffile]如果文件存在
if[-d...]如果目录存在
if[-sfile]如果文件存在且非空
if[-rfile]如果文件存在且可读
if[-wfile]如果文件存在且可写
if[-xfile]如果文件存在且可执行
整数变量表达式
if[int1-eqint2]如果int1等于int2
if[int1-neint2]如果不等于
if[int1-geint2]如果>=
if[int1-gtint2]如果>
if[int1-leint2]如果<=
if[int1-ltint2]如果<
字符串变量表达式
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类似)
条件表达式引用变量要带$
if[a=b];then
echoequal
else
echonoequal
fi
[macg@machome~]$shtest.sh
inputa:
5
inputb:
5
noequal(等于表达式没比较$a和$b,而是比较和a和b,自然a!=b)
改正:
if[$a=$b];then
echoequal
else
echonoequal
fi
[macg@machome~]$shtest.sh
inputa:
5
inputb:
5
equal
-eq-ne-lt-nt只能用于整数,不适用于字符串,字符串等于用赋值号=
[macg@machome~]$vitest.sh
echo-n"inputyourchoice:"
readvar
if[$var-eq"yes"]
then
echo$var
fi
[macg@machome~]$sh-xtest.sh
inputyourchoice:
y
test.sh:line3:test:y:integerexpression_r_r_rexpected
期望整数形式,即-eq不支持字符串
=放在别的地方是赋值,放在if[]里就是字符串等于,shell里面没有==的,那是c语言的等于
无空格的字符串,可以加"",也可以不加
[macg@machome~]$vitest.sh
echo"inputa:"
reada
echo"inputis$a"
if[$a=123];then
echoequal123
fi
[macg@machome~]$shtest.sh
inputa:
123
inputis123
equal123
=作为等于时,其两边都必须加空格,否则失效
等号也是操作符,必须和其他变量,关键字,用空格格开(等号做赋值号时正好相反,两边不能有空格)
[macg@machome~]$vitest.sh
echo"inputyourchoice:"
readvar
if[$var="yes"]
then
echo$var
echo"inputiscorrect"
else
echo$var
echo"inputerror"
fi
[macg@machome~]$vitest.sh
echo"inputyourchoice:"
readvar
if[$var="yes"]在等号两边加空格
then
echo$var
echo"inputiscorrect"
else
echo$var
echo"inputerror"
fi
[macg@machome~]$shtest.sh
inputyourchoice:
y
y
inputiscorrect
[macg@machome~]$shtest.sh
inputyourchoice:
n
n
inputiscorrect
输错了也走then,都走then,为什么?
因为if把$var="yes"连读成一个变量,而此变量为空,返回1,则走else[macg@machome~]$shtest.sh
inputyourchoice:
y
y
inputerror
[macg@machome~]$shtest.sh
inputyourchoice:
no
no
inputerror
一切正常
If[$ANS]等价于if[-n$ANS]
如果字符串变量非空(then),空(else)
echo"inputyourchoice:"
readANS
if[$ANS]
then
echonoempty
else
echoempth
fi
[macg@machome~]$shtest.sh
inputyourchoice:回车
empth说明“回车”就是空串
[macg@machome~]$shtest.sh
inputyourchoice:
34
noempty
整数条件表达式,大于,小于,shell里没有>和<,会被当作尖括号,只有-ge,-gt,-le,lt
[macg@machome~]$vitest.sh
echo"inputa:"
reada
if[$a-ge100];then
echo3bit
else
echo2bit
fi
[macg@machome~]$shtest.sh
inputa:
123
3bit
[macg@machome~]$shtest.sh
inputa:
20
2bit
整数操作符号-ge,-gt,-le,-lt,别忘了加-
iftest$age100;then
[macg@machome~]$shtest.sh
test.sh:line4:test:ge:binaryoperatorexpected
iftest$a-ge100;then
[macg@machome~]$shtest.sh
inputa:
123
3bit
逻辑表达式
逻辑非!条件表达式的相反
if[!表达式]
if[!-d$num]如果不存在目录$num
逻辑与–a条件表达式的并列
if[表达式1–a表达式2]
逻辑或-o条件表达式的或
if[表达式1–o表达式2]
逻辑表达式
表达式与前面的=!=-d–f–x-ne-eq-lt等合用
逻辑符号就正常的接其他表达式,没有任何括号(),就是并列
if[-z"$JHHOME"-a-d$HOME/$num]
注意逻辑与-a与逻辑或-o很容易和其他字符串或文件的运算符号搞混了
最常见的赋值形式,赋值前对=两边的变量都进行评测
左边测变量是否为空,右边测目录(值)是否存在(值是否有效)
[macg@mac-home~]$vitest.sh
:
echo"inputthenum:"
readnum
echo"inputis$num"
if[-z"$JHHOME"-a-d$HOME/$num]如果变量$JHHOME为空,且$HOME/$num目录存在
then
JHHOME=$HOME/$num则赋值
fi
echo"JHHOMEis$JHHOME"
-----------------------
[macg@mac-home~]$shtest.sh
inputthenum:
ppp
inputisppp
JHHOMEis
目录-d$HOME/$num不存在,所以$JHHOME没被then赋值
[macg@mac-home~]$mkdirppp
[macg@mac-home~]$shtest.sh
inputthenum:
ppp
inputisppp
JHHOMEis/home/macg/ppp
一个-o的例子,其中却揭示了”=”必须两边留空格的问题
echo"inputyourchoice:"
readANS
if[$ANS="Yes"-o$ANS="yes"-o$ANS="y"-o$ANS="Y"]
then
ANS="y"
else
ANS="n"
fi
echo$ANS
[macg@machome~]$shtest.sh
inputyourchoice:
n
y
[macg@machome~]$shtest.sh
inputyourchoice:
no
y
为什么输入不是yes,结果仍是y(走then)
因为=被连读了,成了变量$ANS="Yes",而变量又为空,所以走else了
[macg@machome~]$vitest.sh
echo"inputyourchoice:"
readANSecho"inputyourchoice:"
readANS
if[$ANS="Yes"-o$ANS="yes"-o$ANS="y"-o$ANS="Y"]
then
ANS="y"
else
ANS="n"
fi
echo$ANS
[macg@machome~]$shtest.sh
inputyourchoice:
no
n
[macg@machome~]$shtest.sh
inputyourchoice:
yes
y
[macg@machome~]$shtest.sh
inputyourchoice:
y
y
以test条件表达式作为if条件
iftest$num-eq0等价于if[$num–eq0]
test表达式,没有[]
iftest$num-eq0
then
echo"tryagain"
else
echo"good"
fi
mantest
[macg@machome~]$mantest
[(1)UserCommands[(1)
SYNOPSIS
testEXPRESSION
[EXPRESSION]
[-n]STRING
thelengthofSTRINGisnonzero-n和直接$str都是非0条件
-zSTRING
thelengthofSTRINGiszero
STRING1=STRING2
thestringsareequal
STRING1!=STRING2
thestringsarenotequal
INTEGER1-eqINTEGER2
INTEGER1isequaltoINTEGER2
INTEGER1-geINTEGER2
INTEGER1isgreaterthanorequaltoINTEGER2
INTEGER1-gtINTEGER2
INTEGER1isgreaterthanINTEGER2
INTEGER1-leINTEGER2
INTEGER1islessthanorequaltoINTEGER2
INTEGER1-ltINTEGER2
INTEGER1islessthanINTEGER2
INTEGER1-neINTEGER2
INTEGER1isnotequaltoINTEGER2
FILE1-ntFILE2
FILE1isnewer(modificationdate)thanFILE2
FILE1-otFILE2
FILE1isolderthanFILE2
-bFILE
FILEexistsandisblockspecial
-cFILE
FILEexistsandischaracterspecial
-dFILE
FILEexistsandisadirectory
-eFILE
FILEexists文件存在
-fFILE
FILEexistsandisaregularfile文件存在且是普通文件
-hFILE
FILEexistsandisasymboliclink(sameas-L)
-LFILE
FILEexistsandisasymboliclink(sameas-h)
-GFILE
FILEexistsandisownedbytheeffectivegroupID
-OFILE
FILEexistsandisownedbytheeffectiveuserID
-pFILE
FILEexistsandisanamedpipe
-sFILE
FILEexistsandhasasizegreaterthanzero
-SFILE
FILEexistsandisasocket
-wFILE
FILEexistsandiswritable
-xFILE
FILEexistsandisexecutable
if简化语句
最常用的简化if语句
&&如果是“前面”,则“后面”
[-f/var/run/dhcpd.pid]&&rm/var/run/dhcpd.pid检查文件是否存在,如果存在就删掉
||如果不是“前面”,则后面
[-f/usr/sbin/dhcpd]||exit0检验文件是否存在,如果存在就退出
用简化if和$1,$2,$3来检测参数,不合理就调用help
[-z"$1"]&&help如果第一个参数不存在(-z字符串长度为0)
["$1"="-h"]&&help如果第一个参数是-h,就显示help
例子
#!/bin/sh
[-f"/etc/sysconfig/network-scripts/ifcfg-eth0"]&&rm-f/etc/sysconfig/network-scripts/ifcfg-eth0
cpifcfg-eth0.bridge/etc/sysconfig/network-scripts/ifcfg-eth0
[-f"/etc/sysconfig/network-scripts/ifcfg-eth1"]&&rm-f/etc/sysconfig/network-scripts/ifcfg-eth1
cpifcfg-eth1.bridge/etc/sysconfig/network-scripts/ifcfg-eth1
[-f"/etc/sysconfig/network-scripts/ifcfg-eth0:1"]&&rm-f/etc/sysconfig/network-scripts/ifcfg-eth0:1