linux中Shell一些例子

2014-02-27 10:48:37Linux媛媛

bash不分区字符串和数值,如需计算数值可用$((……)),但得到的结果不是数值。

函数内接受不了外面的变量传值。

正则表达式在匹配时是偷懒和正确匹配的和资源开销的一种权衡。

$# 脚本的参数个数

$* 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个

$$ 脚本运行的当前进程ID号

$! 后台运行的最后一个进程的进程ID号

$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数

$- 显示shell使用的当前选项,与set命令功能相同

$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

$0 脚本名称

$1$9 第N个参数

函数基本使用:

function functname{

shell commands

}

or

functname(){

shell commands

}

bash的算术运算比较运算符\字符串比较运算符\文件比较运算符:

煮酒品茶:这个是比较全的。查一般的,请点这里。

1、算术运算比较运算符(bash自身不能比较浮点数)

-eq 等于 [ $num1 -eq $num2 ]

-ne 不等于 [ 100 -ne $num1 ]

-lt 小于 [ 100 -lt `expr $num1 + $num2` ]

-le 小于或等于 [ 100 -le `expr $num1 \* $num2` ]

-gt 大于 [ 100 -gt `expr $num1 / $num2` ]

-ge 大于或等于 [ 100 -ge `expr $num1 % $num2` ]

2、字符串比较运算符

-z string 如果 string 长度为零,则为真 [ -z “`ps aux | grep mysql`” ]

-n string 如果 string 长度非零,则为真 [ -n “$string” ]

【注意】 $string 一定要放在双引号里面 “$string”,否则使用 -n -z 的结果都为真!

string1 != string2 如果 string1 与 string2 不同,则为真 [ “$str1” != “Snail” ]

string1 == string2 如果 string1 与 string2 相同,则为真 [ “$str1” == “$str2” ]

(上面用一个 = 也可以,在严格的 POSIX 兼容下使用)

string1 string2 如果 string1 按字典顺序比较大于 string2,则为真

3、文件比较运算符

-a filename 如果 filename 存在,则为真 [ -e $HOME/.bashrc ]

-e filename (同上)

-b filename 如果 filename 存在,并且是块文件,则为真 [ -e /dev/loop0 ]

-c filename 如果 filename 存在,并且是字符文件,则为真 [ -e /dev/ttyS0 ]

-d filename 如果 filename 存在,并且为目录,则为真 [ -d /home/snail ]

-f filename 如果 filename 存在,并且为常规文件,则为真 [ -f /dev/ttyS0 ]

-g filename 如果 filename 存在,并且为set-group-id,为真 [ -f $HOME/ak47 ]

-h filename 如果 filename 存在,并且为符号连接,则为真 [ -h /bin/vi ]

-L filename (同上)

-k filename 如果 filename 存在,并且设置了sticky位,为真 [ -k /bin/ping ]

-p filename 如果 filename 存在,并且为有名管道(FIFO),真 [ -p /tmp/pipe ]

-r filename 如果 filename 存在,并且可读,则为真 [ -r /etc/passwd ]

-s filename 如果 filename 存在,并且大小不为零,为真 [ -s 。/none-zero ]

-u filename 如果 filename 存在,并且为set-user-id,为真 [ -f $HOME/ak47 ]

-w filename 如果 filename 存在,并且可写,则为真 [ -w /var/log/mail ]

-x filename 如果 filename 存在,并且可执行,则为真 [ -x 。/start.sh ]

下面这些不常用的:

-t fd 如果文件描述符被打开并指向一个终端,则为真 [ -t /proc/1/fd/10 ]

【提示】在 /proc/进程号/fd 下可以找到文件描述符:)

-O filename 如果 filename 存在,并且被有效用户ID所拥有,则为真

-G filename 如果 filename 存在,并且被有效组ID所拥有,则为真

-S filename 如果 filename 存在,并且为一个socket,则为真 [ -S /tmp/mysql.sock ]

-N filename 如果 filename 存在,并且在上次读取后被修改过,则为真

-o optname 如果 shell 选项 optname 被开启,则为真

【提示】使用 set -o 来查看

file1 -nt file2 如果 file1 比 file2 新,或者 file1 存在 file2 不存在,则为真

file1 -ot file2 如果 file1 比 file2 旧,或者 file2 存在 file1 不存在,则为真

file1 -ef file2 如果 file1 和 file2 都指向同样的设备(device)和索引节点号(inode numbers),则为真

【提示】查看文件的索引节点可以用 ls -i 选项

元字符

描述

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配字符“n”。“\\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。

^

匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”.*等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”.+等价于{1,}。

匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。

{n}

n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o.

{n,}

n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o.“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m}

m和n均为非负整数,其中n《=m.最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o.“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

当 该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而 默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

。点

匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“[\s\S]”的模式。

(pattern)

匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。

(?:pattern)

匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

(?=pattern)

正 向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例 如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配 “Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从 包含预查的字符之后开始。

(?!pattern)

正 向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如 “Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中 的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?《=pattern)

反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?《=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。

(?

反向否定预查,与正向否定预查类似,只是方向相反。例如“(?

x|y

匹配x或y.例如,”z|food“能匹配”z“或”food“。”(z|f)ood“则匹配”zood“或”food“。

[xyz]

字符集合。匹配所包含的任意一个字符。例如,”[abc]“可以匹配”plain“中的”a“。

[^xyz]

负值字符集合。匹配未包含的任意字符。例如,”[^abc]“可以匹配”plain“中的”plin“。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,”[a-z]“可以匹配”a“到”z“范围内的任意小写字母字符。

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,”[^a-z]“可以匹配任何不在”a“到”z“范围内的任意字符。

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如,”er\b“可以匹配”never“中的”er“,但不能匹配”verb“中的”er“。

\B

匹配非单词边界。”er\B“能匹配”verb“中的”er“,但不能匹配”never“中的”er“。

\cx

匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的”c“字符。

\d

匹配一个数字字符。等价于[0-9]。

\D

匹配一个非数字字符。等价于[^0-9]。

\f

匹配一个换页符。等价于\x0c和\cL.

\n

匹配一个换行符。等价于\x0a和\cJ.

\r

匹配一个回车符。等价于\x0d和\cM.

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于[^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于\x09和\cI.

\v

匹配一个垂直制表符。等价于\x0b和\cK.

\w

匹配包括下划线的任何单词字符。等价于”[A-Za-z0-9_]“。

\W

匹配任何非单词字符。等价于”[^A-Za-z0-9_]“。

\xn

匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,”\x41“匹配”A“。”\x041“则等价于”\x04&1“。正则表达式中可以使用ASCII编码。

\num

匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,”(。)\1“匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm.

\nml

如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml.

\un

匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(?)。

while基本用法:

while [ condition ]

do

command1

command2

command3

done

#!/bin/bash

sudo find -type f -name ‘*.log’ |while read mvname

do

mv $mvname ${mvname/.log/.LOG}

done

#!/bin/bash

#查找当前目录下*.log并把值赋于mvname参与循环。

sudo find -type f -name ‘*.log’ |while read mvname

do

#移动,并把结尾的。log替换成。LOG /*Ubuntu 下好像不行*/

mv $mvname ${mvname/.log/.LOG}

done

例:上面是一例批量替换文件名的bash

简单PD文件类型,可按照上面文件类形表来写:

#!/bin/bash

if [ $# -ne 0 ]; then

if [ -d $1 ]; then

echo $1 is a Mulu

else

echo $0 D1 D2

fi

if [ -d $2 ]; then

echo $2 is a mulu

else

echo $0 D1 D2

fi

fi

#!/bin/bash

#如果个数不为空的话

if [ $# -ne 0 ]; then

#如果$1第一个参数是目录的话

if [ -d $1 ]; then

echo $1 is a Mulu

else

echo $0 D1 D2

fi

if [ -d $2 ]; then

echo $2 is a mulu

else

echo $0 D1 D2

fi

fi

程序只是例子,中间有很多BUG,例如如果有三个参数?

使之变成函数来表达:

#!/bin/bash

set -x

isd1(){

echo $0 D1 D2

}

if [ $# -eq 2 ]; then

if [ -d $1 ]; then

echo $1 is a Mulu

fi

if [ -d $2 ]; then

echo $2 is a mulu

fi

else

isd1

fi

计算数值变化:

cwtea@CN:/bash$ cat nubmer.sh

#!/bin/bash

a=1

b=2

echo $a+$b

echo $(($a+$b))

cwtea@CN:/bash$ sudo sh nubmer.sh

1+2

3

nagios监控LVS脚本:

煮酒品茶:ly_cyz应该也是混51CTO的,明天问下他,$(())里是不是有些多余?没联系上自己改下脚本再尝试一下。

#!/bin/bash

#Author: ly_cyz

ACT_COUNT=0

Inactive_count=0

stat1=`sudo ipvsadm | grep http | grep Masq|wc -l`

if [ $stat1 -ne 0 ];then

for NUM in `sudo ipvsadm | grep http | grep Masq | awk ‘{print $5}’`

do

ACT_COUNT=$(($ACT_COUNT+ $NUM))

done

for NUM in `sudo ipvsadm | grep http | grep Masq | awk ‘{print $6}’`

do

Inactive_count=$(($Inactive_count+ $NUM))

done

else

echo ”LVS CRITICAL, “LVS is Down”“

exit 2

fi

if [ $ACT_COUNT == 0 ];then

echo ”LVS ok, “0 active connection”“

exit 1

else

echo ”LVS OK - LVS is running (conn: $ACT_COUNT active, $Inactive_count inactive)|active=$ACT_COUNT;69999;99999;0; inactive=$Inactive_count;69999;99999;0;“

fi

编辑后:

#!/bin/bash

#Author: ly_cyz cwtea v2.0

#去除多一个管道,这个你懂得。减少两个赋值。

stat1=`sudo ipvsadm | grep http |wc -l`

if [ $stat1 -ne 0 ];then

for NUM in `sudo ipvsadm | grep http | awk ‘{print $5}’`

do

#取消其数值运算。

ACT_COUNT=$NUM

done

for NUM in `sudo ipvsadm | grep http | awk ‘{print $6}’`

do

Inactive_count=$NUM

done

else

echo ”LVS CRITICAL, “LVS is Down”“

exit 2

fi

if [ $ACT_COUNT -eq 0 ];then

echo ”LVS ok, “0 active connection”“

exit 1

else

echo ”LVS OK - LVS is running (conn: $ACT_COUNT active, $Inactive_count inactive)|active=$ACT_COUNT;69999;99999;0; inactive=$Inactive_count;69999;99999;0;“

fi

相关教程
图文教程