unix shell编程(读书笔记2):分支与循环

判断
if 命令的一般格式:
if command
then
 command
 command
 ...
fi

其中,command需要执行并检测其退出状态,为零:0 执行语句段,否则,不执行。
退出状态,
在unix中,程序执行完后,会返回给系统一个退出状态,按约定 :0成功, 非0 则运行失败。
grep命令:找到指定模式返回0,否则返回非0,如没找到,或当参数不对或文件打不开是而出错时。
管道线的退出状态为其中最后一个命令的退出状态。
$cat whologgedon
#
#判断用户是否登录到了系统
#
user="$1"
if who|grep "$user"
then
 echo "user is logged on"
fi
$

这里grep不仅返回推出状态还会完成它的正常功能,即把匹配的行写入它的标准输出,
而我们世界上对此并不关心。 我们可以把grep 的标准输出重定向到系统的”垃圾桶“:/dev/null,把它的输出去掉。
/dev/null 是系统的一个特殊文件,任何人都可以从它读取(立即得到文件结束指示))或向它写入,上面的whologgedon的程序有些问题,如:bob没登录而bobzhang或者zhangbob或者zhabobng登录了,我们在查bob时显示bob登录了。
修改如下:
$cat whologgedon
#
#判断用户是否登录到系统 v2
#
user="$1"
if who | grep "^$user " >/dev/null
then
 echo "$user is logged on"
fi
$
^:让模式限定在匹配行的开头
user后面的空格:who 把用户名输出在每一行的第一列,后面跟一个或多个空格。于是利用这一特定作为用户名字段的结束标志。(观察who命令的输出特征)

test命令:
test expression test的另外一种表达形式[expression]
expression要测试的条件。 真 0, 假非0
$name= #name is null
$test $name = julio #系统只给了test两个参数 =和julio
sh:test:argument expected
$
$test "$name" = julio "" #系统给了test三个参数null,= 和julio。null以双引号为占位符的方式提供
echo $? #显示退出状态,$?:上一个代码或者shell程序在shell中退出的情况
1 #假
$

test字符串操作
操作符 返回真(退出状态为0)的条件

String1=String2 String1跟String2相同
String1!=String2 String1和String2不相同
String String不为空
-n string String不为空(并且test能看到String)
-z string String为空(并且test能够看到String)

test整数操作
操作符
int1 -eq int2 int1 等于 int2
int1 -ge int2 int1 大于等于int2
int1 -gt int2 int1 大于或者等于int2
int1 -le int2 ...
int1 -lt int2
int1 -ne int2

test常用的文件操作
操作符
-d file file 为目录
-e file file 存在
-f file file 为普通文件
-r file file 为进程可读文件
-s file file 长度不为0
-w file file 为进程可写文件
-x file file 可执行
-L file file为符号化链接

命令:
[-f /users/steve/phone] 检测文件/users/steve/phone是否存在并且是普通文件,即不是普通文
件也不是特殊文件
if [ -f /db2/lddd077/sqllib/db2profile ]; then
 . /db2/lddd077/sqllib/db2profile
LIBPATH=/db2/lddd077/sqllib/lib32:$LIBPATH
fi

逻辑非操作符!
[! -r /users/steve/phone] #/users/steve/phone 不可读时返回退出状态0
逻辑与操作符 -a #有一个表达式为假,结果为假

[-f "$mailfile" -a -r "$mailfile"] # $mailfile变量指向的文件存在,并可读


小括号 ()
改变求值顺序(优先级),小括号本身对shell有特殊也有,所以在用到它的时要转义
["$count" -lt 10 -a \(-f "$mailfile" -a -r "$mailfile"\)]
逻辑或操作符 -o #有一个表达式为真,结果为真
[-f "$mailfile" -o -r "$mailfile"]
else:
if [...] then
...
else
...
fi
whologgedon程序的改进:
$cat whologgedon
#
#判断某人是否登录了 v3
#
#检查提供的参数数目是否正确
#保证传递正确的参数数目是shell变成的一个良好风格
#
if["$#" -ne 1]
then
 echo "Incorrect number of arguments"
 echo "Usage: on user"
else
 user="$1"
 if who | grep "^$user " > /dev/null
 then
 echo "$user is logged on"
 else
 echo "$user is not logged on"
 fi
fi
$

##注意:test后面更的是一个表达式,表达式加上test变成了一个命令,才有了退出状态返回值
##而这里 who | grep "^$user " > /dev/null 是一个命令,他自己会返回一个退出状态,
##所以 who | grep "^$user " > /dev/null 外层就不要套 [ ] 了

exit 命令:
可以通过exit命令指定返回退出状态:exit n #n为返回的退出状态
exit可以立即终止shell程序的执行。如果在终端上执行exit,会导致从系统注销。这其实也更能让人理解shell其实也是一个使用程序,只不过是包装在core外围的。如果不指定n,则会采用exit之前最后所执行命令的退出状态

elif 结构
if command1
then ...
elif ...
else ...
fi


case 命令:
case value in
0) echo zero;;
1) echo 0ne;;
...
esac
$

特殊模式匹配字符:
shell允许在case语句中用一些特殊的字符指定匹配模式,就更文件名替换中一样。
即:?表示任一个字符;×表示0或多个任意字符;[...]表示方括号所办函字符中的任意个。

空命令
:
其目的就是什么也不干,在大多数情况下,用它来瞒住有些地方必须有命令的要求。
特别是在if命令中。

 && 和 || 结构
 shell的&& 和 ||结构,可以根据前一命令执行的成败决定后面命令的执行。
 command1 && command2
 先执行command1,如果退出状态为0,则执行command2
 command1 || command2
 先执行command1,如果退出状态为非零0,则执行command2
 [-z "$EDITOR"] && EDITOR=/bin/ed #检测变量EDITOR的值,如果为空,就把/bin/ed赋值给它
 grep "$name" phonebook || echo "Couldn't find $name" #grep 失败时,显示找不到名字

如果 urfile中包含 flg 则,显示 have delete, 否则显示 have not, ok。
grep -q "flg" urfile && {echo "have";echo "delete";} ||{echo "have not";echo "ok"}
这个写法类似于3元运算符


 循环:
 for var in word1 word2 ... word3
 do
command
 command
 ...
 done

for var in word[1-4] #array
 do
 ...
 done

for var in $* #文件名替换
 do
 ...
 done

for var in $@ #文件名替换和$*一样
 do
 ...
 done

不带列表的for
for var #没有in shell会自动将命令行键入的所有参数依次组织称列表,就跟有 in "$@" 一样
 do
 ...
 done

while 循环
while command1
do
 ...
done

while 通常和shift命令结合使用,
$cat prargs
#
#print command line arguments one per line
#
while ["$#" -ne 0]
do
 echo "$1"
 shift
done

until 命令
until command1 #知道条件满足就推出:command1的返回退出状态为0
do
 command
done

sleep 非shell内部命令,unix命令,挂起当前进程,让它休眠指定时间
#××× nohup and at and cron计划
break 中断循环
continue 跳过循环体中continue后面的命令,继续执行。在done 后面加一个& 就可以把循环放到后台执行

$for file in work[1-4]
>do
> run workcommand
>done & #放到后台执行

循环的输入、输出重定向
$for file in work[1-4]
>do
> run workcommand
>done > loopout #将循环输出重定向到loopout

通过管道项循环输入或接受循环的输出数据
$for file in work[1-4]
>do
> run workcommand
>done |wc -l
在单行中键入循环命令

$for i in 1 2 3 4; do echo $i; done #加分或将各部分隔离
$if[1=1]; then echo yes; else echo no; fi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值