Linux Shell脚本攻略-持续运行命令直至执行成功+字段分隔符和迭代器+比较与测试

持续运行命令直至执行成功

repeat()
{
	while true
	do
		$@ && return
	done

repeat() { while true; do $@ && return; done }
}

函数repeat()中包含了一个while无限循环,该循环执行以函数参数形式(通过$@访问)传入的命令。如果命令执行成功,则返回,进而退出循环

  1. 一种更快的做法
    在大多数现代系统中,true是作为/bin中的一个二进制文件来实现的。这就意味着每执行一次while循环,shell就不得不生成一个进程。可以使用shell的内建命令:,该命令的退出状态总是为0,从而优化代码运行速度
repeat() { while :; do $@ && return; done }
  1. 加入延时
    假设要用repeat()从网上下载一个暂时不可用的文件,不过这个文件只需要等一下就能下载,一种方法如下
repeat wget -c http://www.example.com/software-0.1.tar.gz
# 这会产生很多发往www.example.com的流量,服务器可能会认为这是攻击,从而把IP地址列入黑名单

# 加入延时,解决这个问题
repeat() { while :; do $@ && return; sleep 30; done }

字段分隔符和迭代器

内部字符分割符(Internal Field Separator, IFS)是一个环境变量,其中保存了用于分隔的字符,是当前shell环境使用的默认定界字符串

data="name, gender, rollno, location"

oldIFS=$IFS
IFS=','
for item in $data;
do 
	echo Item: $item
done

IFS=$oldIFS
#Item: name
#Item: gender
#Item: rollno
#Item: location

IFS的默认值为空白字符(换行符、制表符或空格)

#!/bin/bash
line="root:x:0:0:root:/root:/bin/bash"
oldIFS=$IFS
IFS=":"
count=0
for item in $line;
do
	[ $count -eq 0 ] && user=$item;
	[ $count -eq 6 ] && shell=$item;
done;
IFS=$oldIFS
echo $user's shell is $shell

输出为
root’s shell is /bin/bash

  1. 面向列表的for循环
for var in list;
do
	commands; # 使用变量$var
done
# list可以是一个字符串,也可以是一个值序列

我们可以使用echo命令生成各种值序列

echo {1..50}; # 生成一个从1-50的数字序列
echo {a..z}{A..Z}; # 生成大小写字母序列

for i in {a..z}; do actions; done;

  1. 迭代指定范围的数字
for((i=0;i<10;i++))
{
	commands; # 使用变量$i
}
  1. 循环到条件满足为止
    当条件为真时,while循环继续执行;当条件不为真时,until循环继续执行
while condition
do 
	commands;
done
# 用true作为循环条件能产生无限循环

=0;
until [ $x -eq 9 ];
do
	let x++; echo $x;
done

比较与测试

程序中的流程控制是由比较语句和测试语句处理的。可以用if、if else 以及逻辑运算符来比较数据项。此外,还有一个test命令也可以用于测试

# 1. if条件
if condition;
then
	commands;
fi

# 2. else if和else
if conditions;
then	
	commands;
else if conditions; then
	commands;
else
	commands;
fi

if和else语句可以嵌套使用。if的条件判断部分可能会变得很长,但可以用逻辑运算符将它变得简洁一点
[ condition ] && ation;如果condition为真,则执行action
[ condition ] || action;如果condition为假,则执行action
&&是逻辑与运算符,||是逻辑或运算符

  1. 算术比较
    比较条件常被置于封闭的中括号内
[ $var -eq 0 ] # 当$var等于0时,返回真
[ $var -eq 0 ] # 当$var不为0时,返回真

-gt 大于
-lt 小于
-ge 大于或等于
-le 小于或等于

-a是逻辑与操作符,-o是逻辑或操作符。可以按照下面的方法结合多个条件进行测试

[ $var1 -ne 0 -a $var2 -gt 2 ] # 使用逻辑与-a
[ $var1 -ne 0 -o $var2 -gt 2 ] # 逻辑或-o
  1. 文件系统相关测试

[ -f $var ] 检查变量是否包含正常的文件路径或文件名
[ -x $var ] 变量是否可执行
[ -d $var ] 变量是否为目录
[ -e $var ] 变量包含的文件是否存在
[ -c $var ] 变量是否为字符设备文件的路径
[ -b $var ] 变量是否为块设备文件的路径
[ -w $var ] 变量是否可写
[ -r $var ] 变量是否可读
[ -L $var ] 变量是否为一个符号连接

fpath= "/etc/passwd"
if [ -e $fpath ];  then
	echo File exists;
else
	echo Does not exist;
fi
  1. 字符串比较
    使用字符串比较的时候,最好使用双中括号,因为有时采用单个中括号会产生错误

双中括号是Bash的一个扩展特性,如果出于性能考虑,使用ash或dash来运行脚本,那么将无法使用该特性

  • [[ $str1 = $str2 ]] 当str1等于str2时,返回真
  • [[ $str1 == $str2 ]]
  • [[ $str1 != $str2 ]] 如果str1和str2不相同,则返回真
  • [[ $str1 > $str2 ]] 如果str1的字母序比str2大,则返回真
  • [[ $str1 < $str2 ]] 如果str1的字母序比str2小,则返回真
  • [[ -z $str1 ]] 如果str1为空串,则返回真
  • [[ -n $str1 ]] 如果str1不为空串,则返回真

使用逻辑运算符&&和||能够很容易地将多个条件组合起来

str1="Not empty"
str2=""
if [[ -n $str1 ]] && [[ -z $str2 ]];
then
	echo str1 is nonempty and str2 is empty string.
fi

test命令可以用于测试条件,用test可以避免使用过多的括号,增强代码的可读性
可以将if [ $var -eq 0 ]; then echo "True" ; fi也可以写成if test $var -eq 0; then echo "True"; fi

注意,test是一个外部程序,需要衍生出对应的进程,而[是Bash的一个内部函数,因此后者的执行效率更高。test兼容Bourne shell、ash、dash等

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值