shell 比较运算符一览表

运算符 描述 示例
文件比较运算符 
-e filename 如果 filename 存在,则为真 [ -e /var/log/syslog ]
-s filename 如果 filename 存在且不为空,则为真 [ -s /var/log/syslog ]
-d filename 如果 filename 为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename 为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename 为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename 可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename 可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename 可执行,则为真 [ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)  
-z string 如果 string 长度为零(zero),则为真 [ -z "$myvar" ]
-n string 如果 string 长度非零(non-zero),则为真 [ -n "$myvar" ]
string1 = string2 如果 string1 与 string2 相同,则为真 [ "$myvar" = "one two three" ]
string1 != string2 如果 string1 与 string2 不同,则为真 [ "$myvar" != "one two three" ]
算术比较运算符
num1 -eq num2 等于 [ 3 -eq $mynum ]
num1 -ne num2 不等于 [ 3 -ne $mynum ]
num1 -lt num2 小于 [ 3 -lt $mynum ]
num1 -le num2 小于或等于 [ 3 -le $mynum ]
num1 -gt num2 大于 [ 3 -gt $mynum ]
num1 -ge num2 大于或等于 [ 3 -ge $mynum ]

注:以上比较符也适用于 Linux 命令 /bin/test

 

算术运算符 

+ - * / % 表示加、减、乘、除、取余运算

+=、 -=、 *=、 /= 同 C 语言中的含义

 

位操作符

> >>= 表示位左右移一位操作

& &= | |= 表示按位与、位或操作

~ ! 表示非操作

^ ^= 表示异或操作

 

关系运算符 

= == != 表示大于、小于、大于等于、小于等于、等于、不等于操作

&& || 逻辑与、逻辑或操作

 

测试命令

test命令用于检查某个条件是否成立,它可以进行数值、字符和文件3个方面的测试,其测试符和相应的功能分别如下

(1)数值测试:

-eq 等于则为真。

-ne 不等于则为真。

-gt 大于则为真。

-ge 大于等于则为真。

-lt 小于则为真。

-le 小于等于则为真。

(2)字串测试:

= 等于则为真。

!= 不相等则为真。

-z 字串 字串长度为0,则为真。

-n 字串 字串长度不为0,则为真。

(3)文件测试:

-e 文件名,如果文件存在,则为真。

-r 文件名,如果文件存在且可读,则为真。

-w 文件名,如果文件存在且可写,则为真。

-x 文件名,如果文件存在且可执行,则为真。

-s 文件名,如果文件存在且至少有一个字符则为真

-d 文件名,如果文件存在且为目录,则为真。

-f 文件名,如果文件存在且为普通文件,则为真。

-c 文件名,如果文件存在且为字符型特殊文件,则为真。

-b 文件名,如果文件存在且为块特殊文件,则为真

 

条件变量替换

Bash Shell可以进行变量的条件替换,既只有某种条件发生时才进行替换,替换条件放在{}中.

(1) ${value:-$word}

当变量未定义或者值为空时,返回值为word的内容,否则返回变量的值.

## value 未赋值场景
$ value=""
$ word="hello"
$ echo ${value:-$word}   # value为空, 返回word赋值
hello
$ echo $value

## value 有赋值场景
$ value="mimvp.com"
$ word="hello"
$ echo ${value:-$word}   # value不为空, 返回value赋值
mimvp.com
$ echo $value
mimvp.com

 

(2) ${value:=$word}

与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将 word赋值给value 

## value 未赋值场景
$ value=""
$ word="hello"
$ echo ${value:=$word}   # value为空, 返回word赋值, 并把word赋值给value
hello
$ echo $value            # value为空, 已获得了赋值 【区分点】
hello

## value 有赋值场景
$ value="mimvp.com"
$ word="hello"
$ echo ${value:=$word}   # value不为空, 返回value赋值
mimvp.com
$ echo $value
mimvp.com

 

(3) ${value:?$message}

若变量已赋值的话,则正常替换。否则将消息message送到标准错误输出(若此替换出现在Shell程序中,那么该程序将终止运行)

## value 有赋值场景
$ value="mimvp.com"
$ message="you are blank, i love you"
$ echo ${value:?$message}     # value有赋值, 返回value赋值
mimvp.com

## value 未赋值场景
$ value=""
$ message="you are blank, i love you"
$ echo ${value:?$message}     # value无赋值, 返回message提示信息
-bash: value: you are blank, i love you

 

(4) ${value:+$word}

若变量已赋值的话,才用word去赋值,否则不进行任何赋值。注意:value 值一直不会变

示例:

## value 未赋值场景
$ value=""
$ echo $value

$ echo ${value:+"hello world"}   # value 未赋值,条件不成立,不进行赋值

$ echo $value

## value 有赋值场景
$ value="mimvp.com"           
$ echo $value      
mimvp.com
$ echo ${value:+"hello world"}   # value 有赋值,条件成立,进行赋值
hello world
$ echo $value      # value 本身不变 【切记!】
mimvp.com

 

(5) ${value:offset:length}

${value:offset:length} 从变量中提取子串,这里offset和length可以是算术表达式.

offset 下标从0开始计算,表示第一个字符。

$ value="mimvp.com"
$ echo ${value:2:3}   # 下标从0开始, 第三个字符串开始截取, 截取长度为3
mvp

 

(6) ${#value}   变量的字符个数

示例:

$ value="mimvp.com"
$ echo ${#value}      # 获取字符串的长度
9
$ echo ${#value[@]}   # 获取数组的长度
1
$ echo ${#value[*]}   # 获取数组的长度
1

 

(7) ${value#pattern}  ${value##pattern}

二者都是去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配

#与##的区别在于:

前者是最短匹配模式,删除第一个匹配符左侧的内容

后者是最长匹配模式,删除 最末个匹配府左侧的内容

示例:

$ value="mimvp.com mimvp.cn"
$ pattern="mimvp
$ 
$ echo $value
mimvp.com mimvp.cn

$ echo $pattern
mimvp
$ 
$ echo ${value#*.}    # 从左侧第一个匹配, 删除左侧内容
com mimvp.cn
$ echo ${value##*.}   # 从左侧最末个匹配, 删除左侧内容
cn
$
$ echo ${value%.*}    # 从右侧第一个匹配, 删除右侧内容
mimvp.com mimvp
$ echo ${value%%.*}   # 从右侧最末个匹配, 删除右侧内容
mimvp

用法详解,请见米扑博客:Shell 提取文件路径中的文件名、后缀、目录

(8) ${value%pattern}  ${value%%pattern}

与(7)用法类似,只是是从value的尾部与pattern相匹配,%与%%的区别与#与##一样

 

(9) ${value/pattern/string}   ${value//pattern/string}

进行变量内容的替换,把与pattern匹配的部分替换为string的内容,

/与//的区别: / 只匹配第一个并替换; // 匹配所有的并全部替换

示例:

$ value="mimvp.com mimvp.cn"
$ pattern="mimvp"
$
$ echo $value
mimvp.com mimvp.cn
$ echo $pattern
mimvp
$
$ echo ${value/m/*}     # / 只匹配第一个并替换
*imvp.com mimvp.cn
$
$ echo ${value//m/*}    # // 匹配所有的并全部替换
*i*vp.co* *i*vp.cn

小结

上述字符串的条件变量替换中,除(2)外,其余均不影响变量本身的值

 

 

逻辑运算符 -a -o

#!/bin/bash

var1="1"
var2="2"

下面是“”运算符-a,另外注意,用一个test命令就可以了,还有if条件后面的分号

if test $var1 = "1"-a $var2 = "2" ; then
   echo "equal"
fi

兼容性更好的用法格式:

if [ c1 ] && [ c2 ]; then
…
fi

实例应用(算术比较,非字符串比较):

#if [ -n "$1" -a "$1" -eq "1" ]; then       ### 报错 
if [ -n "$1" ] && [ "$1" -eq "1" ]; then   ### 正确
    is_force_run_server=$1
fi
#if [ -n "$2" -a "$2" -eq "1" ]; then       ### 报错 
if [ -n "$2" ] && [ "$2" -eq "1" ]; then   ### 正确
    is_force_kill_firefox=$2
fi

 

下面是“”运算符 -o,有一个为真就可以

if test $var1 != "1" -o $var2 != "3" ; then
   echo "not equal"
fi

兼容性更好的用法格式:

if [ c1 ] || [  c2 ]; then
…
fi

实例应用:

a=0
b=1
if [ $a = 1 ] || [ $b = 1 ]; then
	echo "good"
fi

 

test 多逻辑判断的完整示例:

#!/bin/bash

var1="1"
var2="2"
var3="3"

if test $var1 = "1" -o $var2 = "2"; then
    echo "equal"
else
    echo "no equal"
fi

if test $var1 = "1" -o $var2 = $var3; then
    echo "no equal"
fi

运行结果:

equal

no equal

 

“非”运算符 !

if条件是为真的时候执行,如果使用!运算符,那么原表达式必须为false

if ! test $var1 != "1"; then
   echo "not 1"
fi

以上三个if都为真,所以三个echo都会打印

示例:

#!/bin/sh

aa="August 15, 2012"
bb="August 15, 20122"
cc="123"
dd="123"

# -o
if [ "$aa" = "$bb" -o "$cc" = "$dd" ]; then
	echo "yes"
else
	echo "no"
fi

# -a and !
if [ "$aa" != "$bb" -a "$cc" = "$dd" ]; then
	echo "yes"
else
	echo "no"
fi

运行结果:

true

 

Shell 字符串比较、判断是否为数字

二元比较操作符,比较字符串或者比较数字,注意数字与字符串的区别.

1、 整数比较

-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"))

小数据比较可使用AWK,借助 bc 计算浮点数值。

 

整数比较实例

#!/bin/bash


file='folder_url_top24/url_usa_top24_0'
fileSize=`ls -l folder_url_top24/url_usa_top24_0 | awk -F '[" "]' '{print $5}'`
FILESIZE=1000
#while [ ! -f $file -o "$fileSize" -lt "$FILESIZE" ]
#while [ ! -f $file -o "$fileSize" -lt 1000 ]
while (("$fileSize" < 1000)) 
do
    echo "down again..."
done

其中,下面三种整数比较都成立:

1) while [ ! -f $file -o "$fileSize" -lt "$FILESIZE" ]

2) while [ ! -f $file -o "$fileSize" -lt 1000 ]

3) (("$fileSize" < 1000))

推荐使用第一种

 

2、 浮点数比较

shell(bash) 本身没有小数、浮点数计算,但可以借助 bc 命令(高精度的计算器工具)实现浮点数计算,也可以利用awk进行浮点数计算

bc – An arbitrary precision calculator language

例如,我们要计算linux服务器的负载情况,获取5分钟平均负载情况,大于5则杀死一些进程

1)top 查看负载

# top -b | head -n1

top - 13:14:54 up 47 days, 18:40,  1 user,  load average: 1.32, 0.81, 0.05

 

2) awk 获取5分钟平均负载

# top -b | head -n1 | awk '{print $12}' | cut -d ',' -f1

1.32

解释命令:

a) top -b 获取文本格式,否则会报错  shell illegal character: ^[

b)awk '{print $12}'  获取第12个字段(起始下标为1),即5分钟平均负载值

c) cut -d ',' -f1   分割5分钟平均负载值(1.32,)注意:第12个字段有一个逗号

 

3)bc 计算浮点数

常量示例:

if [ `echo "1.1 > 1" | bc` -eq 1 ];then
    echo "OK"
fi

 

变量示例:

load_average_num=`top -b | head -n1 | awk '{print $12}' | cut -d ',' -f1`
load_average_MaxNUM=5
if [ $(echo "$load_average_num > $load_average_MaxNUM"|bc) -eq 1 ]; then
    echo "kill python..." >> $log
    ps -ef | grep -v grep | grep 'python' | awk '{print $2}' | xargs kill -9
    ps -ef | grep -v grep | grep 'main.py' | awk '{print $2}' | xargs kill -9
fi

 

实际应用的完整示例:

######  monitor load average  by  mimvp.com  ######
load_average_num=`top -b | head -n1 | awk '{print $12}' | cut -d ',' -f1`
load_average_MaxNUM=5
echo "load_average_num: $load_average_num"
echo "load_average_num: $load_average_num" >> $log

#while [ `echo "1.1 > 1" | bc` -eq 1 ]; do
#while [ `echo "$load_average_num > $load_average_MaxNUM" | bc` -eq 1 ]; do
while [ $(echo "$load_average_num > $load_average_MaxNUM"|bc) -eq 1 ]; do
    echo "load_average_num: $load_average_num > load_average_MaxNUM: $load_average_MaxNUM" >> $log
    echo "kill python, firefox..." >> $log

    ps -ef | grep -v grep | grep 'python' | awk '{print $2}' | xargs kill -9
    ps -ef | grep -v grep | grep 'main.py' | awk '{print $2}' | xargs kill -9
    ps -ef | grep -v grep | grep 'firefox' | awk '{print $2}' | xargs kill -9
    ps -ef | grep -v grep | grep 'Xvfb' | awk '{print $2}' | xargs kill -9
    sleep 10

    load_average_num=`top -b | head -n1 | awk '{print $12}' | cut -d ',' -f1`
    echo "restart load_average_num: $load_average_num" >> $log
done

 

3、 字符串比较

=       等于,如: if [ "$a" = "$b" ]

==     等于,如: if [ "$a" == "$b" ] ,与=等价

注意:== 的功能在 [[ ]] 和 [] 中的行为是不同的,如下:

1 [[ $a == z* ]]    # 如果$a以"z"开头(模式匹配)那么将为true

2 [[ $a == "z*" ]] # 如果$a等于z*(字符匹配),那么结果为true

3

4 [ $a == z* ]      # File globbing 和word splitting将会发生

5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么结果为true

一点解释,关于 File globbing 是一种关于文件的速记法,比如"*.c"就是,再如~也是.

但是 file globbing 并不是严格的正则表达式,虽然绝大多数情况下结构比较像.

!=  不等于,如:if [ "$a" != "$b" ]

这个操作符将在 [[ ]] 结构中使用模式匹配.

 

< 小于

在ASCII字母顺序下,如:

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

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

注意:在[]结构中"< "需要被转义,推荐使用双中括号 [[ ]]

 

> 大于

在ASCII字母顺序下.如:

if [[ "$a" > "$b" ]]

if [ "$a" \> "$b" ]

注意:在[]结构中">"需要被转义,推荐使用双中括号 [[ ]]

应用例子

-z  字符串为"null",就是长度为0

-n  字符串不为"null",长度不为0(实际是大于0)

 

判断shell传入的参数个数是否为空

#!/bin/bash

port=6379		# 命令行没参数,默认指定端口号为 6379
if [ $# -ge 1 ]; then	# 命令行参数个数大于等于1,则使用传入的参数port
	port=$1		# 获取指定端口号
fi
	
echo "redis port: $port"
redis-cli -h 172.1628.10.114 -p $port

 

字符串比较实例:

if [ "$var1" = "$var2" ]

代码:

#!/bin/sh

aa="August 15, 2012"
bb="August 15, 2012"

if [ "$aa" = "$bb" ]; then
	echo "yes"
else
	echo "no"
fi

判断子字符串包含关系: =~

代码:

a1="ithomer"
a2="ithomer.net"
a3="blog.ithomer.net"

if [[ "$a3" =~ "$a1" ]]; then
         echo "$a1是$a3的子串!"
else
         echo "$a1不是$a3的子串!"
fi

if [[ "$a3" =~ "$a2" ]];then
         echo "$a2是$a3的子串!"
else
         echo "$a2不是$a3的子串!"
fi

 

注意:

使用-n在[]结构中测试必须要用""把变量引起来.

使用一个未被""的字符串来使用! -z或者就是未用""引用的字符串本身,放到[]结构中。

虽然一般情况下可以工作,但这是不安全的。习惯于使用""来测试字符串是一种好习惯.

awk '{print $2}' class.txt | grep '^[0-9.]' > res

 

 

Shell 中 if 做比较

1、shell判断数组中是否包含某个元素

ary=(1 2 3)
a=2
if [[ "${ary[@]}" =~ "$a" ]] ; then
    echo "a in ary"
else
    echo "a not in ary"
fi

 

2、判读字符串($str)是否包含另一个字符串($str1)

方法1:

if [  `echo $str | grep -e '$str1'`  ] ; then
    echo yes
fi

方法2:

如果 $str1 在判断中直接使用字符串而不是变量,则不能加引号,如if [[ $str =~ ^dx ]]判读字符串$str是否以dx开头,^dx不能加引号:

if [[ $str =~ $str1 ]] ; then
    echo yes
fi

 

3、比较两个字符串是否相等的办法是:

if [ "$test"x = "test"x ]; then

这里的关键有几点:

1)使用单个等号

2)注意到等号两边各有一个空格:这是unix shell的要求

3)注意到"$test"x最后的x,这是特意安排的,因为当$test为空的时候,上面的表达式就变成了x = testx,显然是不相等的。而如果没有这个x,表达式就会报错:[: =: unary operator expected

 

if 判断式

if [ 条件判断一 ] && (||) [ 条件判断二 ]; then

elif [ 条件判断三 ] && (||) [ 条件判断四 ]; then

else

   执行第三段內容程式

fi

 

示例1:

flag=0
webip=''
retry_NUM=3
retry_idx=0

while [ "$flag" -gt "0" -a "$retry_idx" -lt "$retry_NUM" ] || [ -z "$webip" -a "$retry_idx" -lt "$retry_NUM" ]
do
    retry_idx=`expr $retry_idx + 1`
    sleep $retry_idx

    echo "flag: $flag , webip: $webip , retry_NUM: $retry_NUM , retry_idx: $retry_idx  "
done

运行结果:

flag: 0 , webip:  , retry_NUM: 3 , retry_idx: 1
flag: 0 , webip:  , retry_NUM: 3 , retry_idx: 2
flag: 0 , webip:  , retry_NUM: 3 , retry_idx: 3 

 

示例2:

# a=0
# b=0
# c=5         
# if [ $a = 0 -a $b = 0 ]&&[ $c != 0 ]; then
> echo success
> fi
success

 

Linux Shell if 判断写成一行

示例:

[[ $? -eq 0 ]] && echo "backup $i success" || exit

# 判断上一个命令是否执行正确,退出状态码若为0,则执行 echo

否则,会认为[[ $? -eq 0 ]] && echo "backup $i success" 这一段执行错误,不会执行echo,会退出

 

 

Linux Shell 脚步获取当前的函数名

在C/C++中,__FUNCTION__常量记录当前函数的名称。有时候,在日志输出的时候包含这些信息是非常有用的。

在Bash中,同样有这样一个常量 FUNCNAME,但是有一点区别是,它是一个数组而非字符串,其中数组的第一个元素为当前函数的名称。

为什么 FUNCNAME 要是一个数组呢?看看下面的例子,你就明白了。

示例代码:

#!/bin/bash

function test_func()
{
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
    another_func
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
}

function another_func()
{
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
}

echo "Out of function, \$FUNCNAME => (${FUNCNAME[@]})"
test_func
echo "Out of function, \$FUNCNAME => (${FUNCNAME[@]})"

运行结果:

Out of function, $FUNCNAME => ()
Current test_func, $FUNCNAME => (test_func main)
Current another_func, $FUNCNAME => (another_func test_func main)
Current test_func, $FUNCNAME => (test_func main)
Out of function, $FUNCNAME => ()

所以,更加准确地说,FUNCNAME 是一个数组,但是bash中会将它维护成类似一个堆栈的形式。

更详细介绍,请见米扑博客:Linux Shell 脚本获取当前目录和文件夹名

 

 

if 使用的表达式

[ -a 文件 ] 如果文件存在为真。

[ -b 文件 ] 如果 文件 存在 而且 是一个 块-特殊 文件为真。

[ -c 文件 ] 为真 如果 文件 存在 而且 是一个 字-特殊 文件。

[ -d 文件 ] 为真 如果 文件 存在 而且 是一个 目录。

[ -e 文件 ] 为真 如果 文件 存在。

[ -f 文件 ] 为真 如果 文件 存在 而且 是一个 普通 文件。

[ -g 文件 ] 为真 如果 文件 存在 而且 已经设置了他的 SGID 位。

[ -h 文件 ] 为真 如果 文件 存在 而且 是一个 符号连接。

[ -k 文件 ] 为真 如果 文件 存在 而且 他的粘住位已经设置。

[ -p 文件 ] 为真 如果 文件 存在 而且 是一个 已经命名的管道 (F 如果O)。

[ -r 文件 ] 为真 如果 文件 存在 而且 是可读的。

[ -s 文件 ] 为真 如果 文件 存在 而且 比零字节大。

[ -t FD ] 为真 如果 文件 文件描述符已经打开 而且 指向一个终端。

[ -u 文件 ] 为真 如果 文件 存在 而且 已经设置了他的 SUID (set user ID)位。

[ -w 文件 ] 为真 如果 文件 为真 如果 文件 存在 而且 是可写的。

[ -x 文件 ] 为真 如果 文件 存在 而且 是可执行的。

[ -O 文件 ] 为真 如果 文件 存在 而且 属于有效用户ID。

[ -G 文件 ] 为真 如果 文件 存在 而且 属于有效组ID。

[ -L 文件 ] 为真 如果 文件 存在 而且 是一个 符号连接。

[ -N 文件 ] 为真 如果 文件 存在 而且 has been mod 如果ied since it was last read。

[ -S 文件 ] 为真 如果 文件 存在 而且 是一个 socket。

[ 文件1 -nt 文件2 ] 为真 如果 文件1 has been changed more recently than 文件2, or 如果文件1 存在 而且文件2 does not

[ 文件1 -ot 文件2 ] 为真 如果 文件1 比 文件2 旧, 或者 文件2 存在而且 文件1 不存在。

[ 文件1 -ef 文件2 ] 为真 如果 文件1 而且 文件2 refer to the same device 而且 inode numbers。

[ -o 选项名 ] 为真 如果 shell 选项 "选项名" 开启。

[ -z STRING ] 为真 如果 "STRING"的长度是零。

[ -n STRING ] 或者 [ STRING ] 为真 "STRING"的长度是非零值。

[ STRING1 == STRING2 ] 如果两个字符串相等为真。 "=" 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" 是 -eq, -ne, -lt, -le, -gt or -ge 其中一个。 These arithmetic binary operators return 为真 如果 "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" 而且 "ARG2" are integers。

表达式可以借以下操作符组合起来, listed in decreasing order of precedence:

操作符效果

[ ! EXPR ] 如果EXPR 为假则为真。

[ ( EXPR ) ] 返回EXPR 的值。 这样可以用来忽略正常的操作符优先级。

[ 表达式1 -a 表达式2 ] 如果表达式1 而且表达式2 同时为真则为真 。

[ 表达式1 -o 表达式2 ] 如果表达式1 或者表达式2 其中之一为真则为真。

 

shell 中变量间接引用:

假设a=b,b=123,如何通过a获得123呢,通过变量间接引用可以做到:eval a=\$$b (bash版本2中a=${!b}也可以做到)

 

Linux Shell 中 \w \s \d \b ^ $ 等常用匹配用法

正则表达式 \w \s \d \b 用法:

. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字,等价于[0-9]
\D 匹配非数字字符

\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

其中,[^A-Z]表示除了不包含大写字母,^取反;^[A-Z]表示以大写字母开头

示例:

grep -P "^test\s" /etc/ppp/chap-secrets

只匹配 test开头且其后为空白的字符串行,不匹配 test2 , test_3 这样的字符串行

例如:

# grep -P "^test\s+" /etc/ppp/chap-secrets  
test        *       Test201205      *     此行匹配
test2       *       Test201205      *    不匹配
test3       *       Test201205      *    不匹配

 

 

参考推荐:

Linux Shell 算术运算

Linux 之 shell 算术运算符

Linux Shell 函数返回值

Linux shell 局部变量与全局变量

Linux shell 生成随机数和随机字符串

Linux shell 脚本通过expect实现自动输入密码

Centos7 配置 sendmail、postfix 端口号25、465

Shell 提取文件路径中的文件名、后缀、目录 (推荐

Linux Shell 脚本获取当前目录和文件夹名

Shell 参数含义 $0、$1、$2、${n}、$#、$@、$*、$?、 $_、$!、$$

网络DNS域名转换成IP地址

公共 DNS 服务器 IP 地址

域名命名规则