shell总结

 

 

Catalog  

Catalog   .... 2

Catalog   .... 2

命令格式... 7

一.shellUnix平台.... 7

二.shell基本知识.... 7

三.grep 命令.... 9

四.sed.. 9

五.awk命令.... 9

六.find命令.... 10

七.test命令.... 10

八.expr命令.... 11

九.流程控制语法.... 11

1. if-then-elif-else-fi语句... 11

4. for语句... 13

6. while语句... 14

7. until 语句... 14

8. breakcontinue.. 15

9. case 语句... 15

十.shell脚本调试.... 16

实例讲解.... 18

一.模式匹配.... 18

1ls显示所有以hosts.开头的文件... 18

2ls显示包含x,y,z字符的所有文件... 18

二.正则表达式.... 18

1grep匹配/etc/services文件中以ftp字符串开头的哪些文本行... 18

2grep匹配以system文本结尾的行。... 18

3grep匹配仅包含一个#字符的行。... 18

4grep匹配以<abc>或者[abc]开头的行... 18

5grep匹配以Ftp或者ftp开头的行... 18

6grep匹配F或者f以外的字符... 18

7grep匹配除大写字符以外的字符... 18

8grep匹配以ftptelnet开头的文本行... 18

9grep匹配以ftp开头,后跟0个或多个-agent的文本行... 18

10grep匹配以ftp开头,后跟1个或多个-agent的文本行... 18

11grep匹配带有数字6,后跟至少30的文本行(使用-E启用边界特性).. 18

12grep匹配含有(abc)的文本... 18

13.常用正则表达式举例... 18

14grep精确匹配:在抽取字符串后加/>... 19

15grep消除大小写:加入-i选项... 19

16.特殊字符:$ . ‘ “ * [ ] ^ | / + ?.. 19

17grep判断变量含有[HOST]字符串... 19

18grep判断变量含有[xxx]字符串... 20

20.使用grep在文件中查找变量... 20

21.正则表达式语法... 20

三.sed命令.... 23

1sed文本的定位方法:... 23

2sed编辑命令... 24

3sed打印文件的第二行... 24

4sed打印文件的第一到三行... 24

5sed打印匹配test的行... 24

6sed打印匹配$的行... 24

7sed打印最后一行:$是代表最后一行的特殊字符... 24

8sed脚本文件... 24

9sed上例中... 24

10sed上例中... 24

11sed删除第一行... 24

12sed删除第一到第三行... 24

13sed删除最后一行... 25

14sed替换文本... 25

15sed输出到文件,w选项:... 25

16sed从文件读取,r选项:... 25

17sed优势:... 25

18sed常见的一行命令集... 25

19sed去掉字串变量前后的空格... 25

21sed提取最后一个目录名和程序名... 26

22dirname或参数扩展提取目录名... 26

23grep,sed获取文件的扩展名... 27

24sed获取第n个匹配的行的行号... 27

四.awk命令.... 27

1awk字段分隔符:... 28

2awk匹配模式... 28

3awk“模式匹配-动作.. 28

4awk内部变量... 28

5awk用户定义变量... 28

6awk算术运算... 29

7awk高级算符... 29

8awk内部算术函数... 29

9awk内置函数... 29

10awk的自定义函数... 30

11awk下一语句:... 31

12awk中的字符串相加:.. 31

13awk的逻辑运算符... 31

14awk的逻辑与||、逻辑或&&.. 31

15awkFSOFSORS使用:... 31

16awksprintf函数的使用... 31

17awk的重定向,输出到文件:... 31

18awk删除文件的第一行... 32

19awk删除输入行中特定行的换行字符... 32

20awk获取输入行中,域的最大个数... 32

21awk输出一行超过80 个字符的每一行... 32

22awk输出至少一个域的所有行。可用来将一个文档里的所有空白行删除... 32

23awk输出范围在0 100 之间的7 个随机数... 32

24awk将所有用户的login名称依照字母的顺序输出... 32

25awk将一个文档的总行数输出... 32

26awk输出文档的内容时会在每行的最前面输出行号它的功能与'cat -n' 类似... 32

27awk自定义函数的例子一: 第一个域与第二个域的平方和... 32

28awksplit、数组、注释... 32

29awk打印传入字符串的第n个分隔域。... 33

30.在awk中使用shell中的变量... 33

31.在某个目录下查找包含特定字符串的文件。返回文件名称... 35

五.其它命令.... 35

1eval命令:可用于动态生成和执行代码... 35

2exit         n:退出... 36

3export导出环境变量... 36

4shift命令:... 36

5shell的参数扩展:... 36

6<<即时文档... 37

7sh调试选项... 37

8time命令测试一个程序执行时间... 37

9expr命令... 37

10if语句判断变量是否为某个值(防止空串)... 38

13touch命令... 38

14touchmake联合使用强制编译... 38

15dd命令传送文件... 39

16talk命令... 39

17ps命令... 39

18rm指令... 39

19find命令... 39

21rusers命令... 39

22cal命令... 40

25find命令... 40

26cut命令... 40

27paste命令... 41

28rm命令... 42

30cat命令... 42

32groupaddmkgroup命令... 43

33ln命令... 43

34su命令... 43

35setenv命令... 43

36repeat命令... 43

38sort命令... 44

38kill命令和trap命令... 45

39.操作系统和数据库检查(IBM)(一):检查核心参数的配置... 45

40.操作系统和数据库检查(IBM)(二):检查时区的配置... 46

41.操作系统和数据库检查(IBM)(三):检查硬件错误... 46

42.操作系统和数据库检查(IBM)(四):检查硬盘错误... 46

43.操作系统和数据库检查(IBM)(五):检查交换区的使用情况... 46

44.操作系统和数据库检查(IBM)(六):检查内存的使用情况... 46

45.操作系统和数据库检查(IBM)(七):检查系统的运行情况... 46

46.操作系统和数据库检查(IBM)(八):检查文件系统的使用情况... 46

47.操作系统和数据库检查(IBM)(九):检查文件系统的属性... 47

48.操作系统和数据库检查(IBM)(十):HACMP检查... 47

49.操作系统和数据库检查(IBM)(十一):检查数据库的DR状态... 47

50.操作系统和数据库检查(IBM)(十二):检查数据库的运行状态... 47

51.操作系统和数据库检查(IBM)(十三):数据库检查... 48

52.操作系统和数据库检查(IBM)(十四):检查数据库的运行日志... 49

53fsck命令... 49

54useraddmkuser命令... 49

54exec命令... 49

54tr命令... 50

六.杂项.... 50

1setenv PATHset path = (....) 50

2awk中输出单引号... 50

3awkread找出文件行字符数大于80的行... 50

4shell脚本程序中的用户切换:... 51

5shell中删除文件且不显示输出信息和出错信息... 51

6shell变量赋初值时存在特殊字符... 51

7sed的参数串中存在/特殊字符... 51

9shell中确定一个文件的存在,文件ins_billdb. 52

10read的参数与实际域的个数不同... 52

12grep确定变量不是数字... 53

13.确定字符串是否是ip地址... 53

15grepawk列出某个目录下的一级子目录... 54

16.用printf将一个数打印成逗号分隔的形式... 54

17iTELLIN示例一:在ksh中使用数组... 55

18iTELLIN示例二:从文件中读取参数:... 56

19iTELLIN示例三:包含其它脚本文件... 57

20iTELLIN示例四:初始化一个临时文件供使用... 58

21iTELLIN示例五:分解字符串... 58

22iTELLIN示例六:替换配置文件中的值... 59

24iTELLIN示例八:用另外的文件作为函数库... 60

25iTELLIN示例九:解压缩文件到一个目录... 61

26iTELLIN示例十:判断操作是否成功... 63

27iTELLIN示例十一:封装创建一个组的函数... 64

28iTELLIN示例十二:封装创建一个用户的函数... 65

29iTELLIN示例十三:判断一个字符串是否是正整数... 67

30iTELLIN示例十四:判断当前用户是否有root权限... 68

31iTELLIN示例十五:判断一个字符串是否是整数... 68

32iTELLIN示例十六:删除某个文件夹下若干天以来未改动的文件... 68

33.各种Unix环境对ksh的影响:.. 69

34set 使用注意点:.. 69

35.判断对端节点的文件是否存在:.. 70

36awksplit函数的使用:.. 70

37.统计字符串在文件中出现的次数:.. 70

38.如何进行精确匹配:.. 73

39.给系统登录的用户发消息... 75

40.输出到stderr.. 75

 


命令格式

一.shellUnix平台

Unix平台

shell

FreeBSD3.4

/bin/sh

SGI IPIX6.5

/sbin/sh

HUPX-11

usr/bin/sh

UnixWare 7

$SHELL/bin/sh

Solaris 8 (固有的)

/usr/bin/sh

Solaris 8 (标准的)

/usr/bin/ksh

IBM AIX 4.3

/usr/bin/sh

IBM AIX 4.3 (可信的)

/usr/bin/tsh

Linux

/bin/sh

 

 

 

二.shell基本知识

脚本参数:

shell脚本参数可以任意多,但只有前9各可以被访问,使用shift命令可以改变这个限制。参数从第一个开始,在第九个结束。

$0 程序名字

$n n个参数值,n=1..9

$* 所有命令行参数

$@   所有命令行参数,如果它被包含在引号里,形如$@,则每个参数也各自被引号包括

$# 命令行参数个数

$$ 当前进程的进程ID(PID)

$!  最近后台进程的进程ID

$?  最近使用命令的退出状态

其他参数:

$CDPATH 包含一系列目录名,cd命令对他们诸葛进行搜索来查找作为参数传递给它的目录;如果该变量未设置,cd命令搜索当前目录

$EDITOR 程序(e-mail程序)里使用的默认编辑器

$ENV    UNIX查找配置文件的路径

$HOME   用户初次登录时的起始目录名

$MAIL   用户的系统邮箱文件的名称

$MAILCHECK  shell检查用户邮箱是否有新邮件并将结果通知用户的间隔时间(以秒为单位)

 

$PATH   包含用户的搜索路径的变量—shell用来搜索外部命令或程序的目录

$PPID   父进程的进程ID

$PS1    系统第一个提示符,一般为$

$PS2    系统第二个提示符,一般为>

$PWD    当前工作目录的名称

$TERM   用户的控制终端的类型.

$LINENO 所在的代码行,一般用来输出错误行号

shift [n]       将命令行参数往左移n位,但$0不变

export  变量名表 将变量名表所列变量传递给子进程

read    变量名表 从标准输入读字符串,传给指定变量

echo    变量名表 将变量名表指定的变量显示到标准输出

set     显示设置变量

env     显示目前所有变量

 

set命令可以重新设定参数表.set hello  wold命令会设定$*为字符串hello world$n$#也同时受影响。

shift命令可以将所有参数左移一个单位,$*$n$#均受影响。

 

数组(在sh中不支持,可以在ksh中使用):

${#varlist[@]}      数组元素个数

${datalist[index]}  数组元素

${#datalist[index]} 数组元素长度

    执行命令:

1)     command :直接执行命令command

2)     sh command:启动一个shell process执行命令command

3)     .  command:在本process中执行命令command

4)     exec command:Script将会被所执行的命令所取代,当这个命令执行完毕之後,本Script也会随之结束。

 

echo 命令使用的特殊字符

    /b      退格

    /c      显示新行,但是不把光标移到下一行

    /f      换页

    /n      换行(光标移到下一行)

    /r      回车

    /t      水平制表符

    /v      垂直制表符

    //      反斜杠

    /ON     ASCII码为八进制数N的字符

 

set命令:

    把各位置参数的值依次设为”argument-list”里指定的参数,即重新设置$*,$@,$1-$9

    : set “hello”  “world”

    $*$@都变成 hello world

    $1hello

    $2world

 

三.grep 命令

    搜索文本的匹配内容。

格式:   grep  [-option]  pattern  [filename]

选项:

    -c  只输出匹配行的计数

    -i  不区分大小写(只适用于单字符)

    -h  查询多文件时不显示文件名

    -l  查询多文件时只输出包含匹配字符的文件名

    -n  显示匹配行及行号

    -s  不显示不存在或无匹配文本的错误信息

    -v  显示不包括匹配文本的所有行

 

四.sed

    查找和编辑文本。

格式:

直接键入命令 

sed  [-option]  command_line  filename

sed命令插入脚本文件,然后调用sed

sed  [-option]  -f  program_file  filename

sed命令插入脚本文件,并使脚本可执行

sed  program_file  [-option]  filename

选项:

n  不打印;sed不把编辑行写到标准输出,默认为打印所有行(编辑的和未编辑的)。

p命令可以用来打印编辑行。

c  下一个命令是编辑命令。在使用多项编辑时要加入该选项。

f  如果正在调用sed脚本,要使用此选项。此选项sed脚本支持所有的sed命令。

 

 

五.awk命令

    awk 是一种程序语言,对于资料的处理具有很强的功能,对于文档里的资料做修改、比较、抽取等处理,awk 能够以很短的程序轻易地完成。如果使用C 语言写程序完成上述的操作不方便且很花费时间,所写的程序也会很大。

    awk 能够依照用户定义的格式来分解输入的资料也可以依照用户定义的格式来打印资料。

    awk 可用于在对象文件中逐行读取记录,按照命令中定义的匹配模式寻找相关记录,然后对该记录进行操作动作。

格式:

(1)直接键入命令:

awk  [-Fchar] ‘command_line’  filename

(2)awk命令插入脚本文件,然后调用awk:

awk  -f  program_file  filename

       前一种形式的-Fchar确定间隔符,command_line为操作动作,filename为对象文件。

       后一种形式的program_file是指用户按一定格式编制好的对对象文件的匹配与操作。

 

六.find命令

通过文件名或其它特征查找文件。

格式:

    find [path-list] [predicate-list]

选项:

    -type   tp  文件类型为tp:

        b   块特别文件

        c   字符设备特别文件

        d   目录文件

        f   普通文件

        p   管道文件(FIFO)

        s   socket

        I   符号链接文件

    -user  uname 文件属于用户uname

    -group gname    文件属于组gname

    -size   n   文件是n块大小(每块512字节),若n后跟一个c,单位为字节。

    -atime  n       n天内已访问过此文件。

    -mtime n        n天内已修改过此文件

    -ctime  n       n天内文件被修改、属性(拥有者、组、链接数等)被修改。

    -exec   command {} /;  执行命令

    -print          打印当前路径名

    -newer  file    修改时间比file文件晚

 

七.test命令

命令格式

test expression

expression中包含一个以上的判断准则以作为test评诂的标准。两准则间用"-a" 表逻辑AND 运算,"-o"代表逻辑OR运算,而在准则前放置一"!" 代表NOT 运算。如 果没有括号,则优先权则为"!" > "-a" > "-o" 。和expr命令相同,相使用左右括 号时,必须在其前面加上"/"

以下是有关准则的叙述(符合叙述时传回真,否则传回伪):

string string不为空白字串

-n string string的长度大於0

-z string string的长度等於0

string1=string2 string1等於string2

string1!=string2 string1不等於string2

int1 -gt int2 int1大於int2

int1 -ge int2 int1大於等於int2

int1 -eq int2 int1等於int2

int1 -ne int2 int1不等於int2

int1 -le int2 int1小於等於int2

int1 -lt int2 int1小於int2

-r filename 档案可读取

-w filename 档案可写入

-x filename 档案可执行

-f filename 档案为一般档

-d filename 档案为目录

-s filename 档案为非空的一般档

test -r "$filename" -a -s "$filename"

   

八.expr命令

命令格式

expr expression

    expression是由字串以及运算子所组成,每个字串或是运算子之间必须用空白隔开 。下表是运算子的种类及功能,而优先顺序则以先後次序排列,可以利用小括号来改变运算的优先次序。其运算结果则输出至标准输出上。

: 字串比较。比较的方式是以两字串的第一个字母开始,而以第二个字串的 字母结束。如果相同时,则输出第二个字串的字母个数,如果不同时则传 0

 

/|          OR运算,如果它非null或者非0,返回第一个表达式,否则返回第二个表达式

/&          AND运算,如果非null或非0,返回第一个表达式,否则返回0

=/>/>=/</<!=   整数比较运算符

+-/*/%       整数算术运算符,其中%求余数。

 

expression中含有"*", "(", ")" 等符号时,必须在其前面加上"/" ,以免被 Shell 解释成其它意义。 

expr 2 /* /( 3 + 4 /) 其输出为14

     

九.流程控制语法

    1. if-then-elif-else-fi语句

if expression

then

    [elif expression

    then

        then-command-list]

    . . .

[else

        else-command-list]

fi

if-then-fi语句的语义

                                                           if-then-else-fi语句的语义

if-then-elif-else-fi语句的语义

    4. for语句

for variable [in argument-list]

do

        command-list

done

for语句的语义

 

 

 

for var

do 

        commands

done

       例如

for arg

do

     echo $var

done

    6. while语句

while expression

do

        command-list

done

while语句的语义

    7. until 语句

until expression

do

        command-list

done

until语句的语义

    8. breakcontinue

这两者是用於for, while, until 等循环控制下。break 会跳至done后方执行 ,而continue会跳至done执行,继续执行循环。

 

    9. case 语句

case test-string in

        pat1)

            command-list1

            ;;

        pat2)

            command-list2

            ;;

        . . .

        patN)

            command-listN

            ;;

        *)

            ;;

esac

 case语句的语义

pat 除了可以指定一些确定的字串,也可以指定字串的集合,如下

* 任意字串

? 任意字元

[abc] a, b, c三字元其中之一

[a-n] an的任一字元

| 多重选择,如A|a

 

十.shell脚本调试

    1.启动调试

启动调试Shell脚本的基本语法为:

    $/bin/sh option script arg1 arg2 ... argN

这里显式声明了要执行脚本的Shell/bin/sh,script是脚本的名字,arg1argN是脚本的参数, option为调试选项,如下所示:

    -n   读所有的命令,但不执行它们

    -v   在读时显示所有的行

-x  在执行时显示所有命令和它们的参数。该选项常称为shell 跟踪选项或

改变脚本的第一行,象下面那样在该行声明一个调试选项:

#!/bin/sh option

 

    2.使用set命令

       在每个调用激活调试模式中,调试模式的缺省行为对脚本中从第一行到最后一行都有效。有时我们只需要调试特定的函数或脚本的一部分,这时调试整个脚本就有些多余。通过使用set命令,我们可以在shell脚本的任何地方启动或取消调试,其基本语法为:

set [-|+] option

这里的option选项与上面的相同。

set –x 回显

set –v 详细

#!/bin/ksh -xv

 

    3.语法检查

        在处理任何Shell脚本时,应在准备执行它之前检查脚本的语法,这使我们能改正许多问题。要启动语法检查可使用-n选项,如对于上面的buggy.sh脚本,象下面那样检查语法:

$/bin/sh -n ./buggy.sh

   


实例讲解

一.模式匹配

1ls显示所有以hosts.开头的文件

ls  –l  hosts.*

 

2ls显示包含x,y,z字符的所有文件

ls  –d  *[x-z]*

   

二.正则表达式

    1grep匹配/etc/services文件中以ftp字符串开头的哪些文本行

grep    ‘^ftp’  /etc/services

    2grep匹配以system文本结尾的行。

grep    ‘system$’   file

    3grep匹配仅包含一个#字符的行。

grep    ‘^#$’   file

    4grep匹配以<abc>或者[abc]开头的行

grep    ‘[[<]abc[]>]’   file

    5grep匹配以Ftp或者ftp开头的行

grep    ‘^[Ff]tp’   file

    6grep匹配F或者f以外的字符

grep    ‘[^Ff]’ file

    7grep匹配除大写字符以外的字符

grep    ‘[^A-Z]’    file

    8grep匹配以ftptelnet开头的文本行

grep    -E ‘^ftp|^telnet’   file

    9grep匹配以ftp开头,后跟0个或多个-agent的文本行

grep    ‘^ftp(-agent)?’ /etc/services

  grep    ‘^ftp(-agent)*’ /etc/services

注:

    a)sco unix下,上面的单括号前要加转义符/

    b)sun os 5.8下,不论加不加单括号均不支持。

    10grep匹配以ftp开头,后跟1个或多个-agent的文本行

grep    ‘^ftp(-agent)+’ /etc/services

说明同上。

    11grep匹配带有数字6,后跟至少30的文本行(使用-E启用边界特性)

grep    -E  ‘60/{3,/}’  /etc/services

    12grep匹配含有(abc)的文本

grep    ‘/(abc/)’   file

    13.常用正则表达式举例

正则表达式

匹配功能

^[the]

the开头行

[Ss]igna[lL]

匹配单词signal,signaL,Signal,SignaL

[Ss]igna[lL]/.

同上,但加一个句点

[mayMAY]

 

^USER$

只包含USER的行

[tty]$

tty结尾的行

/.

带句点的行

^d..x..x..x

对用户、用户组及其它用户组成员有可执行权限的目录

^[^l]

排除关联目录的目录列表

[.*0]

0之前或之后加任意字符

[000*]

000或更多个

[iI]

大写或小写I

[iI][nN]

大写或小写In

[^$]

空行

[^.*$]

匹配行中任意字符

^……$

包括6各字符的行

[a-zA-Z]

任意单字符

[a-z][a-z]*

至少两个小写字母

[^0-9/$]

非数字或美元表示

[^0-9A-Za-z]

非数字或字母

[123]

13中的一个数字

[Dd]evice

单词Devicedevice

De..ce

前两个字母为De,后跟两个任意字符,最后为ce

^.$

仅有一个字符的行

^/.[0-9][0-9]

以一个句点和两个数字开始的行

“’Device’”

单词Device

De[Vv]ice/.

单词Device.DeVice.

[0-9]/{2/}-[0-9]/{2/}-[0-9]/{4/}

日期格式dd-mm-yyyy

[1-9][0-9]/{1,2/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}

IP地址格式nnn.nnn.nnn.nnn

[^.*$]

匹配任意行

 

    14grep精确匹配:在抽取字符串后加/>

grep  “48/>”  file

    15grep消除大小写:加入-i选项

grep  -I  “sept”  file

    16.特殊字符:$ . ‘ “ * [ ] ^ | / + ?

       如果要查询这些字符,需要在前面加转义字符/

    17grep判断变量含有[HOST]字符串

if [ "1" -eq "`echo "$VarName" | grep -c '/[HOST/]'`" ]; then

   

    18grep判断变量含有[xxx]字符串

if [ "1" -eq "`echo "$VarName" | grep -c '/[.*/]'`" ]; then

    19grep匹配后缀为c,h,j,s,cpp,hpp的文件

EXT_ALL='chjs'

EXT_PP='ch'

EXT_NO_PP='js'

ls $1 | grep "/.[$EXT_ALL][p]/{0,2/}$" | grep -v  "/.[$EXT_NO_PP][p]/{1,2/}$" | grep -v "/.[$ EXT_PP][p]/{1/}$"  

20.使用grep在文件中查找变量

grep `echo $user` /etc/passwd | cut –f5 –d‘:’

    21.正则表达式语法

    来自msdn,仅供参考。

Here are some examples of regular expressions:

    Expression

Matches

/^/s*$/

Match a blank line.

//d{2}-/d{5}/

Validate an ID number consisting of 2 digits, a hyphen, and an additional 5 digits.

/</s*(/S+)(/s[^>]*)?>[/s/S]*</s*///1/s*>/

Match an HTML tag.

The following table contains the complete list of metacharacters and their behavior in the context of regular expressions:

Character

Description

/

Marks the next character as a special character, a literal, a backreference, or an octal escape. For example, 'n' matches the character "n". '/n' matches a newline character. The sequence '//' matches "/" and "/(" matches "(".

^

Matches the position at the beginning of the input string. If the RegExp object's Multiline property is set, ^ also matches the position following '/n' or '/r'.

$

Matches the position at the end of the input string. If the RegExp object's Multiline property is set, $ also matches the position preceding '/n' or '/r'.

*

Matches the preceding character or subexpression zero or more times. For example, zo* matches "z" and "zoo". * is equivalent to {0,}.

+

Matches the preceding character or subexpression one or more times. For example, 'zo+' matches "zo" and "zoo", but not "z". + is equivalent to {1,}.

?

Matches the preceding character or subexpression zero or one time. For example, "do(es)?" matches the "do" in "do" or "does". ? is equivalent to {0,1}

{n}

n is a nonnegative integer. Matches exactly n times. For example, 'o{2}' does not match the 'o' in "Bob," but matches the two o's in "food".

{n,}

n is a nonnegative integer. Matches at least n times. For example, 'o{2,}' does not match the "o" in "Bob" and matches all the o's in "foooood". 'o{1,}' is equivalent to 'o+'. 'o{0,}' is equivalent to 'o*'.

{n,m}

M and n are nonnegative integers, where n <= m. Matches at least n and at most m times. For example, "o{1,3}" matches the first three o's in "fooooood". 'o{0,1}' is equivalent to 'o?'. Note that you cannot put a space between the comma and the numbers.

?

When this character immediately follows any of the other quantifiers (*, +, ?, {n}, {n,}, {n,m}), the matching pattern is non-greedy. A non-greedy pattern matches as little of the searched string as possible, whereas the default greedy pattern matches as much of the searched string as possible. For example, in the string "oooo", 'o+?' matches a single "o", while 'o+' matches all 'o's.

.

Matches any single character except "/n". To match any character including the '/n', use a pattern such as '[/s/S]'.

(pattern)

A subexpression that matches pattern and captures the match. The captured match can be retrieved from the resulting Matches collection using the $0$9 properties. To match parentheses characters ( ), use '/(' or '/)'.

(?:pattern)

A subexpression that matches pattern but does not capture the match, that is, it is a non-capturing match that is not stored for possible later use. This is useful for combining parts of a pattern with the "or" character (|). For example, 'industr(?:y|ies) is a more economical expression than 'industry|industries'.

(?=pattern)

A subexpression that performs a positive lookahead search, which matches the string at any point where a string matching pattern begins. This is a non-capturing match, that is, the match is not captured for possible later use. For example 'Windows (?=95|98|NT|2000)' matches "Windows" in "Windows 2000" but not "Windows" in "Windows 3.1". Lookaheads do not consume characters, that is, after a match occurs, the search for the next match begins immediately following the last match, not after the characters that comprised the lookahead.

(?!pattern)

A subexpression that performs a negative lookahead search, which matches the search string at any point where a string not matching pattern begins. This is a non-capturing match, that is, the match is not captured for possible later use. For example 'Windows (?!95|98|NT|2000)' matches "Windows" in "Windows 3.1" but does not match "Windows" in "Windows 2000". Lookaheads do not consume characters, that is, after a match occurs, the search for the next match begins immediately following the last match, not after the characters that comprised the lookahead.

x|y

Matches either x or y. For example, 'z|food' matches "z" or "food". '(z|f)ood' matches "zood" or "food".

[xyz]

A character set. Matches any one of the enclosed characters. For example, '[abc]' matches the 'a' in "plain".

[^xyz]

A negative character set. Matches any character not enclosed. For example, '[^abc]' matches the 'p' in "plain".

[a-z]

A range of characters. Matches any character in the specified range. For example, '[a-z]' matches any lowercase alphabetic character in the range 'a' through 'z'.

[^a-z]

A negative range characters. Matches any character not in the specified range. For example, '[^a-z]' matches any character not in the range 'a' through 'z'.

/b

Matches a word boundary, that is, the position between a word and a space. For example, 'er/b' matches the 'er' in "never" but not the 'er' in "verb".

/B

Matches a nonword boundary. 'er/B' matches the 'er' in "verb" but not the 'er' in "never".

/cx

Matches the control character indicated by x. For example, /cM matches a Control-M or carriage return character. The value of x must be in the range of A-Z or a-z. If not, c is assumed to be a literal 'c' character.

/d

Matches a digit character. Equivalent to [0-9].

/D

Matches a nondigit character. Equivalent to [^0-9].

/f

Matches a form-feed character. Equivalent to /x0c and /cL.

/n

Matches a newline character. Equivalent to /x0a and /cJ.

/r

Matches a carriage return character. Equivalent to /x0d and /cM.

/s

Matches any white space character including space, tab, form-feed, and so on. Equivalent to [ /f/n/r/t/v].

/S

Matches any non-white space character. Equivalent to [^ /f/n/r/t/v].

/t

Matches a tab character. Equivalent to /x09 and /cI.

/v

Matches a vertical tab character. Equivalent to /x0b and /cK.

/w

Matches any word character including underscore. Equivalent to '[A-Za-z0-9_]'.

/W

Matches any nonword character. Equivalent to '[^A-Za-z0-9_]'.

/xn

Matches n, where n is a hexadecimal escape value. Hexadecimal escape values must be exactly two digits long. For example, '/x41' matches "A". '/x041' is equivalent to '/x04' & "1". Allows ASCII codes to be used in regular expressions.

/num

Matches num, where num is a positive integer. A reference back to captured matches. For example, '(.)/1' matches two consecutive identical characters.

/n

Identifies either an octal escape value or a backreference. If /n is preceded by at least n captured subexpressions, n is a backreference. Otherwise, n is an octal escape value if n is an octal digit (0-7).

/nm

Identifies either an octal escape value or a backreference. If /nm is preceded by at least nm captured subexpressions, nm is a backreference. If /nm is preceded by at least n captures, n is a backreference followed by literal m. If neither of the preceding conditions exists, /nm matches octal escape value nm when n and m are octal digits (0-7).

/nml

Matches octal escape value nml when n is an octal digit (0-3) and m and l are octal digits (0-7).

/un

Matches n, where n is a Unicode character expressed as four hexadecimal digits. For example, /u00A9 matches the copyright symbol (©).

 

三.sed命令

    sed的正则表达式用//括住。

    1sed文本的定位方法:

x

x为一行号

x,y

表示行号范围从xy

/pattern/

查询包含模式的行

/pattern/pattern/

查询包含两种模式的行

/pattern/,x

在给定行号上查询包含模式的行

x,/pattern/

通过行号和模式查询匹配行

x,y!

查询不包括指定行号xy的行

 

    2sed编辑命令

命令

意思

p

打印匹配行

=

显示文件行号

a/

在定位行号后附加新文本信息

i/

在定位行号后插入新文本信息

d

删除定位行

c/

用新文本替换定位文本

s

使用替换模式替换相应模式

r

从一个文件中读文本

w

将文本写道一个文件

q

第一个模式匹配完成以后退出或立即退出

l

显示八进制ASCII代码等价的控制字符

{}

在定位行执行的命令组

n

从另一个文件中读文本下一行,并附加到下一行

g

将模式2粘贴到/pattern n/

y

传送字符

   

    3sed打印文件的第二行

sed  -n  ‘2p’  filename

    4sed打印文件的第一到三行

sed  -n  ‘1,2p’  filename

    5sed打印匹配test的行

sed  -n  ‘/test/p’  filename

    6sed打印匹配$的行

sed  -n  ‘//$/p’  filename

    7sed打印最后一行:$是代表最后一行的特殊字符

sed  -n  ‘$p’  filename

    8sed脚本文件

#!/bin/sed  –f “/company/” a/ “The  suddenly  it  happen.”

       将以上脚本保存为append.sed,使用chmod给予其可执行权限。使用append.sed  filename运行。脚本的执行将会在filename文件中查找company,在匹配行的后一行中附加新文本,输出到屏幕上(不改变原文件)。

    9sed上例中

如果将a/改为i/:则为插入,在匹配行的前一行中附加新文本,输出到屏幕(不改变原文件)。

10sed上例中

如果将a/改为c/:则为替换,匹配行被替换为新文本。

    11sed删除第一行

sed  ‘1d’   filename

    12sed删除第一到第三行

sed  ‘1,3d’  filename

    13sed删除最后一行

sed  ‘$d’  filename

    14sed替换文本

sed  ‘s/night/NIGHT/’  filename  #将所有night替换为NIGHT

sed  ‘s/night//’  filename           #night删除

    15sed输出到文件,w选项:

把第12行的内容输出到文件field中,不存在则创建。

sed  ‘1,2w field’  filename         

    16sed从文件读取,r选项:

把文件内容附加到匹配行company.之后

sed  ‘/company./r  sedex.txt’  filename

    17sed优势:

用户在获得不同格式的、带有各种奇形怪状格式控制符的文本,需要将它编成易读的文本时,就可以使用sed流编辑程序。另外,在重新处理具有比较固定格式的文本以生成新格式的文本时,也可以使用sed流编辑程序。

    18sed常见的一行命令集

命令

意思

‘s//.$//g’    

删除以句点为结尾行

‘-e/abcd/d’

删除包含abcd的行(疑为’/abcd/d’

‘s/[ ][ ]*/[ ]/g’

删除一个以上空格,用一个空格代替

‘s/^[ ][ ]*//g’

删除行首空格

‘s//.[ ][ ]*/[]/g’

删除句点后跟两个或多个空格,用一个空格代替

‘s/^$/d’

删除空行(sh不支持d,但在ksh下支持)

‘s/^.//g’

删除第一个字符

‘s/COL/(…/)//g’

删除COL以及其后的三个字母

‘s/^g’

删除开头的/

‘s/[ ]*/[ ]/g’ 

删除所有空格并用tab代替

‘s/^[ ]//g’

删除行首的一个tab

‘s/^[ ]*//g’

删除行首的所有tab

‘s/[ ]*//g’

删除所有tab

‘s/[ ]*/[ ]/g’

删除所有tab并用一个空格代替

‘s/[ ][ ][ ][ ]*/[ ]/g’

每四个空格删除并使用一个tab代替

    19sed去掉字串变量前后的空格

    str1=”  1234 “

str2=` echo ${str1} `

此时str2不含有前后的空格。

如果使用sed如下:

str2=”` echo ${str1} | sed ‘s/^[ ]*//g’ | sed ‘s/[ ]*$//g’  `”

如果使用awk如下:

str2=”` echo $(str1) | awk ‘{print $1}’`”

:

str2=”` echo ${str1} | sed ‘s/(^/s*) | (/s*$)//g’  `”

注:使用awksed的缘故是可以和前一次的操作一次性完成,而不必单独使用一条语句去除空格。例如下面第二个awk的作用就是去除空格:

TmpInf1="`echo $TmpInf | awk -F= '{print $2}' | awk '{print $1}'`"

    20sed去除文件count中的前后的空格

tmp=`sed 's/^ *//g' count | sed 's/ *$//g' `

       tmp为文件内容,不含有前后的空格。

    21sed提取最后一个目录名和程序名

例如从../../etc/passwd或者/etc/passwd得到passwd

方法一:使用临时文件

#得到当前路径,输出到a文件

pwd >a

#读取a文件,过滤首字母/和尾字母/,将结果输出到b文件

sed 's/^g' a  | sed ‘s///$//g’ >b

while fgrep // b

do

#读取b文件,过滤首字符串xxxx/,将结果输出到a文件

sed 's/^[a-zA-Z0-9]*g' b >a

#a文件拷贝到b文件

    cp -f a b

done

rm –f a

rm –f b

 

方法二:使用变量(优于文件形式)

c_path=`pwd`

#过滤首字母/和尾字母/

c_path=`echo $c_path | sed 's/^g'  | sed ‘s///$//g’ `

while [ `echo $c_path | grep -c '//'` -gt 0  ]

do

     c_path=`echo $c_path | sed 's/^[a-zA-Z0-9_.]*g'`

done

echo $cur_path

方法三:使用basename命令

c_path=`pwd`

c_path=`basename $c_path`

       注:参数扩展见五.5

    22dirname或参数扩展提取目录名

例如从$0参数中提取运行的路径:../../etc/passwd/得到../../etc,从/etc/passwd得到/etc

       方法一:dirname

c_path=$0

c_path=`dirname $c_path`

注:如果没有路径,则c_path得到为单字符”.”。所以,判断是否在当前路径执行可以使用条件 “-$c_path” = “-.”

       方法二(参数扩展在基本sh下不支持)

c_path=$0

c_path=’${0%/*}’

注:如果没有路径,则c_path得到为文件名,即$0。所以,判断是否在当前路径执行可以使用条件 “-$c_path” = “-$0”

    23grep,sed获取文件的扩展名

例如从../../home/file.c得到c

       方法一:

file=$1

#得到最后一级文件名 ,如file.c

file=`basename $file`

#如果文件名中不含有.,则表示没有后缀

if [ 1 -gt `echo $file | grep -c '/.'` ]; then

    echo "no extion"

else

    #过滤掉最后一个.以及之前的所有字符,得到扩展名

    echo `echo $file  | sed "s/.*/.//g" `

fi

       方法二:(参数扩展在基本sh下不支持)

file=$1

#得到最后一级文件名 ,如file.c

file=`basename $file`

#file的尾部开始删除匹配.*(一个.后跟若干字符)的最小部分并返回剩余部分

echo  "${file%.*}" 

          

24sed获取第n个匹配的行的行号

get_match_line_no()

{

        n=$1            #n个匹配的行

        file=$2         #要搜索的文件

        str=$3          #要匹配的字符串

        sed -n "/${str}/="  ${file} | sed -n "${n}p"

}

注:

若仅仅想匹配第一个,可以用一个sed完成

    sed -n  '/include/ {   

                           =  

                           q  }'  print.cpp

其中: =表示打印行号, q标识匹配第一个就退出。

 

四.awk命令

1awk字段分隔符:

 -F选项指定了字段分隔符为冒号

awk  -F: ‘{print $1,$3}’  file

2awk匹配模式

       分为三类:

a)    awk的关系表达式:

用来说明字段是否与要求符合。例如:$1==”char” $2>20等等。

b)    awk的正则表达式:

//括住。规则与sed相同。

例如:

           /^.$/  匹配只有一个字符的行。

c)    awkBEGINEND模式:

BEGIN模式意味着在读取第1行之前的匹配模式。它常用于初始化,例如设置分隔符、打印标题以及变量赋初值等。END模式是在处理完所有记录行以后的匹配模式。它常常用于输出结果。

3awk“模式匹配-动作”

    a)在每一行中匹配’foo’,若匹配则打印该行

awk  ‘/foo/ {print $0}’  filename

b)在每一行中匹配第一个字段是否为’foo’ 若匹配则打印该行

awk  ‘$1~/foo/ {print $0}’  filename

4awk内部变量

(部分变量需要验证)

变量

含义

默认值

属性

ARGC

命令行实参个数

-

只读

ARGV

命令行实参数组

-

可读可写

FILENAME

当前输入文件名

-

只读

FNR

当前文件中的记录数

-

只读

FS

输入字段分隔符

空白及制表符

可读可写

NF

当前记录中的字段数

-

只读

NR

至今读取的记录数

-

只读

OFMT

数的输出格式

%.6g

可读可写

OFS

输出字段分隔符

空白

可读可写

ORS

输出记录分隔符

换行符

可读可写

RS

输入记录分隔符

换行符

可读可写

RSTART

match()匹配的第一个字符索引

-

只读

RLENGTH

match()匹配的串的长度

-

只读

SUBSEP

下标分隔符

“/34”

只读

CONVFMT

数值的内部转换格式

%.6g

可读可写

   

5awk用户定义变量 

       用户自定义变量用以存放数据以及进行运算。

 

6awk算术运算

   算术运算在内部以浮点形式完成,也包含一般的加、减、乘、除、余和乘幂,运算符分别为”+””-“”*””/””%””^”

awk  ‘$1==”Feb” {sum=$2+$3}  END{print sum}’  filename

awk  ‘$1==”ATOM” {a=a+$2;i=i+1}’  filename

 

7awk高级算符

       ++或者+=等等。

awk ‘$1==”ATOM” {a+=$2;i++}’   filename

8awk内部算术函数

函数名

返回值

cos(x)

x的余弦值,x是弧度

exp(x)

x的幂函数

int(x)

x的整数部分

log()

x的自然对数

rand()

得出一个随机数,此随机数平均分布在0 1 之间。这个值不会是0,也不会是1

每次执行awk rand 产生相同的随机数序列。

sin(x)

x的正弦值,x是弧度

sqrt(x)

x的平方根

srand(x)

x是针对rand()的新的种子。设定产生随机数的开始点或seed 随机数种子为x。如果在第二次你设定相同的seed 值,你将再度得到相同序列的随机数如果省略参数x,则现在的日期时间会被当成seed。这个方法可使得随机数是真正不可预测的srand 的。

  返回值(return value)是前次所设定的seed

 

9awk内置函数

awk的字符串使用引号括起。通过连接常量、变量、数组元素、函数和其它表达式可以创建串表达式。

例如:打印第几号记录和一个冒号,然后打印文本行。

           {print NR”:”$0}

函数名

返回值

gsub(r,x)

在当前记录中,用s替换r,返回替换数

gsub(r,s,t)

在串t中,用s替换r,返回替换数

index(s,t)

返回s串中t的位置,不出现时为0

length(s)

返回s的长度

match(s,r)

返回rs中出现的位置,不出现时为0

split(s,a)

针对FSs分成数组a,返回字段数

split(s,a,r)

针对rs分成数组a,返回字段数

sprintf(fmt,expr_list)

根据格式串fmt返回经过格式编排的expr_list

sub(r,s)

在当前记录中把第一个r替换成s,返回替换数

sub(r,s,t)

t中把第一个r替换成s,返回替换数

substr(s,p)

返回从位置p开始的s的后缀

substr(s,p,n)

返回从位置p开始长度为ns子串

注:

p最小为1,当p0时,p被置为1

n个字符包括p所在字符。

system(cmd)      

执行命令并返回出口状态

toupper(s)

将输入参数s中的字符全部转换为大写字符并返回转换后的字符串

tolower(s)

将输入参数s中的字符全部转换为小写字符并返回转换后的字符串

close( expr )

关闭由expr表示的文件或管道,文件或管道可能被printprintf语句或调用内建函数getline打开。如果成功,函数返回0,否则返回非0

getline

这个内建函数将$0设置为当前输入文件的下一个输入记录,getline <  file将用从file中获得下一条记录修改$0的值,getline x用下一行的内容替换变量x,而$0仍然是当前行的内容。但下一次返回的将是下下一行的内容。cmd | getline将从管道中获得cmd命令的输出。如果成功,getline返回1,遇到文件结尾,getline返回0,出错返回-1

 

 

   

10awk的自定义函数

        格式:

function  func_name(arg_list)

{

}

例如:

将下列代码保存在awk_pro文件中,调用echo 5 | awk –f awk_pro,将得到输出:5!is120

function fact(n)

{  

    if(n<=1)   

        return 1   

    else   

        return n*fact(n-1) 

}      

{print $1”!is” fact($1)}   

数组实参可以通过应用传递,所以针对该函数有可能改变数组元素或创建一个新元素。标量实参将用值传递,形式参数是局部变量,但其它变量都是全局量。

 

11awk的“下一”语句:

next 语句 next file 语句 exit 语句

next语句强迫awk立刻停止处理目前的记录而继而处理下一个记录。

next file类似next,它强迫awk立刻停止处理目前的数据文件而继而处理下一个文件。

exit语句会使得awk程序停止执行而跳出。如果END出现,它会去执行END的动作。

 

12awk中的字符串相加:

str3str + str2 + str

str="hello""world"

str2="----- "

str3=str str2 str

 

13awk的逻辑运算符

    表达式

含义

x==y

x等于y时为真

x>y

x大于y时为真

x>=y

x大于或等于y时为真

x<y

x小于y时为真

x<=y

x小于或等于y时为真

x!=y

x不等于y时为真

x~y

x包含y时为真

x!~y

x不包含y时为真

 

 

    例如:

awk '$2~"aaa" {print $0}' filename

14awk的逻辑与||、逻辑或&&

awk '$2=="bbb" || $2=="ccc" {print $0}' filename

awk '/2400/ && /foo/' BBS-list

awk '/2400/ || /foo/' BBS-list

awk '!/foo/' BBS-list

15awkFSOFSORS使用:

’|’为分隔符输出各个域

awk ‘BEGIN{OFS=”|”}{print $1,$2,$3,$4}’ filename

awk 'BEGIN {OFS=";"; ORS="/n/n"} {print $1, $2}' filename

awk 'BEGIN {FS=","}; {print $2}'

16awksprintf函数的使用

sprintf格式化字符串

print sprintf("%03d", 2);

17awk的重定向,输出到文件:

可以使用>或者>>

print "This is a test" > "fff.txt"

18awk删除文件的第一行

awk ‘{  if (NR % 2 == 1)    printf “%s”, $0 ’

19awk删除输入行中特定行的换行字符

       例如:删除奇数行的换行字符

awk '

{

    if (NR % 2 == 1)

         printf "%s",$0 ;

    else

         print $0

}'

20awk获取输入行中,域的最大个数

awk '{if (NF > max) max = NF} END {print max}'

21awk输出一行超过80 个字符的每一行

awk 'length($0) > 80'

22awk输出至少一个域的所有行。可用来将一个文档里的所有空白行删除

awk '{if (NF > 0) print}'

23awk输出范围在0 100 之间的7 个随机数

awk 'BEGIN {for (i = 1; i <= 7; i++)

print int(101 * rand())}'

24awk将所有用户的login名称依照字母的顺序输出

awk 'BEGIN {FS = ":"} {print $1 | "sort"}' /etc/passwd

25awk将一个文档的总行数输出

awk '{nlines++} END {print nlines}'

awk 'END {print NR}'

26awk输出文档的内容时会在每行的最前面输出行号它的功能与'cat -n' 类似

awk '{print NR,$0}'

27awk自定义函数的例子一: 第一个域与第二个域的平方和

awk ‘{print "sum =",SquareSum($1,$2)}

function SquareSum(x,y)

{

sum=x*x+y*y

return sum

}’

28awksplit、数组、注释

    test.awk 文件:

#!/bin/awk -f

BEGIN

{

    record="123#456#789"

    num=split(record,myarray,"#")

}

END

{

    for(i=1;i<=num;i++)

    {

        print myarray[i]    # print the element of array 

    }

}

调用:

./test.awk /dev/null

   输出:

123

456

789

 

29awk打印传入字符串的第n个分隔域。

       str是字符串,num定义了要打印的域的序号。

str=”abc bcd cde efg”

num=2

echo "$num $str" | awk '{k=$1+1; print $k}'

打印出:

bcd

注:k的值是$1+1而不是$1,因为$num也要算awk的传入参数。

30.在awk中使用shell中的变量

str1="hello  world"

str2="world"

echo "$str1" | eval "awk  '{

if(/$2==/"$str2/")

print(/"$str1/")

}'"

打印

hello  world

另一种方法就是把shell中的变量当参数通过管道传入到awk中。

需求:

已知变量 usr的值为 sms, 要求使用 awk /etc/passwd文件中查找(:为分隔符号), 当匹配到第一个域(name),打印第6个域(home).

所需表达式:

awk –F: ‘{ if($1==”sms”) print $6 }’ /etc/passwd

#!/bin/ksh

#set -x

usr="sms"

# 方法一,使用临时文件 tmp.txt

eval "awk -F: '{ if (/$1==/"$usr/") print /$6 }' /etc/passwd >tmp.txt"

cat tmp.txt

# 方法二,完全使用eval合成

par1='/$1'

par6='/$6'

equal='/"'

eval "cmd=/" awk -F: '{ if ( $par1==$equal$usr$equal ) print $par6 }' /etc/passwd /""

#echo "cmd:$cmd"

home=`eval "$cmd" `

echo $home

:

(1) eval 按照双引号进行展开, 每一对双引号展开一次, 我们例子中的句子:

eval "cmd=/" awk -F: '{ if ( $par1==$equal$usr$equal ) print $par6 }' /etc/passwd /""

awk中引用的变量被两对双引号包括,所以要构造出所需表达式,需要保证$1能将禁得起两次展开:

二次展开定义式:

par1=’/$1’ # 单引号

在两次展开以后就变成了$1

二次展开定义式:

equal=’/”’  # 单引号

在两次展开以后就变成了

由于希望$usr在两次展开之后变成 sms, 所以不需要二次展开定义式,如下定义式:

usr="sms"

在两次展开以后就变成了sms

(2) 当合成cmd以后, 会发现cmd已经合成为:

cmd: awk -F: '{ if ( $1=="sms" ) print $6 }' /etc/passwd

但是不能调用

home=`$cmd`

来获取其输出值 ,而只能使用

home=`eval "$cmd" `

 

方法三(推荐用法):

使用 awk –v参数.

awk –F:  -v usr="$usr" ‘{ if ($1==usr) rint $6 }’ /etc/passwd

:如果有多个参数需要共享,可以使用多个-v参数传入.

其它实现的方法:

# 方法四: 查找以 $usr: 开头的行,打印第6个元素

home=`cat /etc/passwd | grep "^$usr:" | awk -F: '{ print $6 }'`

echo $home

# 方法五: 重新组织行,将要查找的字符串放到首位,各个字符串以空格分隔, 然后查找以 $usr 开头的行,打印相应元素.

# 此方法适用于不以要查找的字符串为开头的行, 重新组织以后,就可以使用方法四.

home=`cat /etc/passwd | awk -F: '{ printf("%s %s/n",$1,$6) }' | grep "^$usr" | awk  '{print

$2 }' `

echo $home

31.在某个目录下查找包含特定字符串的文件。返回文件名称

dir="/opt/informix/*"

find_str="config"

grep  -c  "$find_str"  "$dir"  | awk  'BEGIN{FS=":"}{ print $1 }'

返回找到文件的列表,每行一个文件。

 

五.其它命令

    1eval命令:可用于动态生成和执行代码

foo=10

x=foo

eval        y=’$’$x

echo    $y

输入10,即eval   y=’$’$x被解释为y=$foo,即y=10

nDay1="111"

nDay2="222"

nDay3="333"

# 遍历变量nDay1 ...nDay3,打印其值

for i in 1 2 3

do

    n=$i

    eval nVar='$nDay'$i

    echo $nVar

done

应该依次输出 $nDay1  , $nDay2, $nDay3 ,:

111

222

333

另一个用于数组的例子,

#!/bin/ksh

 

nDay_1[0]=""

nDay_2[0]=""

nDay_3[0]=""

 

k=2

for i in 1 2 3

do

    eval "nDay_$i[$k]=$i"        # 赋值, 型如:nDay_x[n]=$i

    eval "nVar=/${nDay_$i[$k]}"  # 访问, 型如:nVar=${nDay_x[n]}

    echo ${nVar}     # 打印

done

应该依次输出 ${nDay_1[2]}, ${nDay_2[2]}, ${nDay_3[2]}, :

1

2

3

    2exit n:退出

0代表成功,1-125代表出错代码,128以上引发一个信号。

    我们脚本或许会和别的脚本交互,这个时候需要相互传递信息,exit是被调用进程的返回值,调用进程使用$?获得返回值。

注:exitreturn不同,return用于函数返回值,调用函数和被调用函数在同一个进程中,获取返回值都是用$?

    3export导出环境变量

       把参数变量名导出到子shell里,使之成为子shell的环境变量。

    存在a.shb.sh两个shell脚本,在a.sh中调用b.sha.sh使用export输出的变量将成为b.sh的环境变量。

       使用set –a 或者set –allexport将把在它之后声明的任何变量导出为环境变量。

       csh中使用setenv来设置变量。

    4shift命令:

       把所有参数变量向左移动一个位置,但$0不变。每次执行shift,则参数变量左移一个位置,$1变成$2$2变成$3...最右边的那个参数变为空

while [ "$1" != "" ];

do

    echo "$1"

    shift

done

若用户参数为 –m  -n  -z

则上述代码依次输出 :

–m

-n

-z

    5shell的参数扩展:

tmp_1="1111"

tmp_2="2222"

for i in 1 2

do

    eval tmp='$'tmp_${i}

    echo $tmp

done

其中,tmp_${i}为参数扩展的应用。常见参数扩展替换见下表:

参数扩展

说明

${param:-default}

param空,则把它设为default的值

${#param}

给出param的长度

${param%word}

param的尾部开始删除匹配word的最小部分并返回剩余部分(sh不支持,ksh支持)

${param%%word}

param的尾部开始删除匹配word的最大部分并返回剩余部分(sh不支持,ksh支持)

${param#word}

param的头部开始删除匹配word的最小部分并返回剩余部分(sh不支持,ksh支持)

${param##word}

param的头部开始删除匹配word的最大部分并返回剩余部分(sh不支持,ksh支持)

例:将某个文件夹下所有gif文件通过cjpeg程序转换为jpeg文件。

for image in *.gif

do

    cjpeg   $image  >  $(image%%gif)jpg

done

例如:

FILE_NAME=${0##*/}  程序的文件名(不带路径)

BASE_DIR=${0%/*}        程序的路径

其它实例可参见三.22

    6<<即时文档

    开始是”<<”,然后是特殊字符序列,该序列将在文档结尾再次出项。注意,结束的!FUNKY!最好顶格,前后不要留空格。

cat <<!FUNKY!

hello

this is a here

!FUNKY!

    7sh调试选项

       使用”-o”设置选项,使用”+o”取消设置。

命令行选项

set命令选项

说明

sh -n <script>

set  -o  noexec

只检查语法错误,不执行命令

set  -n

sh  -v  <script>

set  -o  verbose

在执行命令之前回显它们

set  -v

sh  -x  <script>

set  -v  xtrace

在处理完命令行之后回显它们

set  -x

set  -o  nounset

如果使用了未定义变量 就给出一条出错信息

 

 

 

 

    8time命令测试一个程序执行时间

        time  test.sh

    9expr命令

x=`expr  10  +  10`

x=`expr  $x  +  10`

x=`expr  $ /*  2 `

       注:加号两边必须有空格,乘号必须有转义符。

    10if语句判断变量是否为某个值(防止空串)

       因为数值的比较操作数不能为空,所以如果变量可能为空,且仅仅是进行等于或者不等于的比较操作时,则应转化为:

if [ "-$VarName" = "-5" ]; then

       而不要使用 if [ $VarName –eq 5 ]; then

       数值测试有如下比较符:

-eq -ne-gt-lt-le-ge

       对于-gt -lt -le ge等其他比较符,有以下两种方法:

a)    先判断是否为空,然后再做比较(适用于确定变量为数字的情况)

b)    先判断为数字,然后再做比较(适用于不确定变量为数字的情况)。

if ["-$VarName" != "-" ]; then

if [ $VarName –gt 5 ]; then

    ......

       或者

is_integer $VarName

if [ $? = 0 ] ; then

if [ $VarName –gt 5 ]; then

......

       注:is_integer函数判断一个串是否是整数,见章节“六.31 iTELLIN示例十五”

       11nm命令察看一下xxx.o文件中是否有多个相同名字的函数

       12psgrepawk显示属于某个用户的所有进程(并杀死)

        方法一:ps + grep

list=ps -e -f | grep USRID

       方法二:ps -u

list=`ps -u $LOGNAME`

       方法三(推荐)ps + grep + awk

list=`ps -u $LOGNAME|grep -v csh|grep -v PID|awk '{print  $1}'`

        说明:

grep –v csh 避免杀死本sh程序(也有可能遗漏一些sh程序)

grep –v PID 由于ps显示有顶行标题,此句可以过滤此行

       杀死程序:

for i in $list

do

    kill -9 $i

done

   13touch命令

       创建以当前时间为文件名的文件:

touch logfile.`date ’+%y%m%d.%H:%M’`

        创建修改时间为19961203:04的文件:

touch  0102030496  file

       注:用两位数字表示年份,2003写作031996写作96

    14touchmake联合使用强制编译

touch *.c

make

       make将发现所有的.c文件都比相应的.o文件具有更新的版本,从而重新编译。

    15dd命令传送文件

       使用 dd指令,可以把一个文件转换成另一个文件,也可以选择文件的一部份传输,在传输的数据中,也可以交换字节顺序。

dd if=/dev/fd0 of=/temp/save skip=5 count=6 bs=5k

       上面的指令″/dev/fd0″ 是指电脑上的软盘,″skip=n″代表在复制到输出文件之前,跳过输入文件上的几个记录。″bs=n″ 表示设置输入输出字节块长度,用 k 表示 1024 字节。″count=n″ 只复制输入记录的指定数,所以上述指令跳过25k字节,拷贝30k字节。

    16talk命令

       与本机用户交谈

talk    user_name

       与在ccsun22主机上的用户交谈

talk    user_name@ccsun22

    17ps命令

-u username〉选项显示指定用户的讯息。

-t ttynamt〉选项显示指定终端有关的进程讯息。

  而ps -elf指令则提供了需有FSCPRINITIME字段的使用讯息:

F是指示进程位置,20表示在内存,0表示交换在盘上, 31是系统进程。

S是指示进程状态,睡眠还是正在运行。

C是进程占有CPU的百分率

TIME是花费CPU的总时间。

PRI是进程当前优先数
   NI是进程的nice ADM)菜单

    18rm指令

-i  征求确认后才会删除

-r <目录>    删除该目录及该目录之下的所有档案

-rf <目录>   同上,但不会先徵求确认

    19find命令

       /usr/ice下查找hihi.c文件或目录,找到后在屏幕上显示

find /usr/ice -name hihi.c -print

    20df命令

显示可使用之档案储存空间及档案数目

df

    21rusers命令

       rusers命令列出远程机器上的用户

       列出网络上各台主机的用户

rusers

       列出sco-gfep主机上的用户

rusers  -l sco-gfep

-l选项以who的格式给出一个表(较详细)

   

    22cal命令

       显示2003年年历

cal  2003

       显示本月月历

cal

       显示2003年九月月历

cal 09 2003

    23tty命令

       显示目前所用终端机名称

    24banner命令

       放大显示字符(个数不超过10):

banner  “1234”

    25find命令

find . -name hello -print 寻找目前目录及所有的子目录内叫hello的文件

find . -size +2000m -print 找出大小超过2000 bytes的档案

find /tmp -user b1234567 -print /tmp下属於b1234567的档案

find . -name '*.c' -exec rm {} /; 删除所有的.c

find . –mtime +6 –print 找出修改时间在6天前的档案

find . -ctime +7 -print 找出七天内未被更动的档案

    26cut命令

        分割文件每一行选择的字段。

cut -c list  [ file ... ]

cut -f list  [ -d delim ]  [ -s ]  [ file ... ]

       选项

-c list 此选项(无空格)确定字符位置list是以逗号分割的字段号码,说明域号的整数表(递增次序),可以用-表示范围,(c表示char):

    -c 1,4,7    字符1,47

    -c 1-8,9    字符138

    -c -5,10    字符1510

    -c 3-       字符3到最后

-f list  此选项确定字段列表,以定界符分隔。没有字段定界符的行将完整传送,(f表示field

    -f  1,7 只拷贝第1和第7个字段。

    -f  1-3    只拷贝第1到第3个字段。

-dchar      紧跟-d的字符char是字段定界符,缺省值为tab,对shell有特殊意义的字符必须用引号引起来。

     -d” “  使用一个空格作为定界符。(d表示define

       例子:

获取当前注册名

who am i | cut -f1 -d" "       

将用户标识符映射成名称

cut  -d:  -f1,5   /etc/passwd 

显示12 34

echo "12 34 567 89 0" | cut -d" " -f 1-2   

显示12345

echo “12345678”   | cut –c 1-5  

       诊断:

I “ERROR: line  too long”

           一行不能超过1023个字符或字段。

         27paste命令

       合并几个文件中的相同行或同一文件其后的相同行。

paste [ -s ]  [ -d list ]  file ...

pastefile1 file2 等的对应行连接起来,将每个文件看成是列或表的各列而将他们水平的粘贴在一起(平行合并)。

选项:

-d 无此选项时,文件中的每个换行符都由tab字符取代,但最后一个文件须除外(或在-s选项时最后一行除外)。此选项允许由list中一个或多个备用字符来替换tab字符(见下)。

list 代替tab成为行连接字符的一个或几个字符。即-d后面的list中的字符将依次作为行连接字符的一个或几个字符。如果是两个或多个文件合并,则作为每个文件行之间的连接字符。如果是一个文件自身合并,则作为每行的连接字符。List可包括:/n(新行)、/ttab)、//(反斜杠)、/0(空行),但不能为null字符。

-s  合并后续行而不是各文件中的行。用tab作为连接符。

-   可代替文件名,以从标准行中读入一行(不给出提示)。

例子:

文件1.txt内容如下

    1 2 3 4 5 6

     a b c d e f

文件2.txt内容如下

    11 22 33 44 55 66

     aa bb cc dd ee ff

连接1.txt2.txt的各行,tab作为行连接字符

    paste  1.txt  2.txt

    输出:

    1 2 3 4 5 6     11 22 33 44 55 66

    a b c d e f     aa bb cc dd ee ff

连接1.txt各行,以空格作为连接字符

    1 2 3 4 5 6 a b c d e f

在一列中列出目录

    ls | paste –

在四列中列出目录

    ls | paste - - - -

将成对行合并成行

    paste  -d “/t/n” –s 1.txt

诊断:

     “line too long:”

    输出字符限制在511

     “too many files:”

     除非用-s选择,否则最多只能指定12个输入文件。

    28rm命令

rm [-f][-i] file

rm [-r[-f][-i] dirname …[file…]

rmdir [-p][-s] dirname

    rm删除一个目录中的一个或多个文件。

选项

-f  此选项删除所有的在目录中的文件(不管是否有无写保护),而不对用户进行提示。在有写保护的目录中不能对文件进行删除,但不显示任何信息。

-r  此选项删除参数中列出的所有目录和子目录。

    例子:

       删除目录mend_check_dir并且不回显

rm -fr $INSTALL_PATH/mend_check_dir >/dev/null 2>&1

29mkdir命令

mkdir在方式777下建立目录(方式可用umask更改).

Mkdir [-mmode][-] dirname ...

       选项:

-m  此选项允许用户指定新目录使用的方式.

-p      使用此选项,可以建立一个名为dirname且在父辈目录中不存在的目录。

       例如:

建立目录dir1/dir2,即使dir1在当前目录中不存在。

mkdir  -p  dir1/dir2    

    30cat命令

       连接和显示文件。

cat [-u][-s][-v][-t][-e] file ...

       cat按顺序读每个file,且将它写到标准输出上。     

       如果未给出文件名,或者遇到变元,cat将从标准输入文件上读。

       例如:

           打印file到终端

     cat  file

           连接file1file2,且把结果写入到file3

    cat  file1   file2  > file3

    31pkgadd命令

       将软件包传送给系统。

        pkgadd [-d device] [-r response][-n][-a admin][pkginst1 [pkginst2[…]]]

pkgadd将软件包的内容从安装它的分布介质或目录转送到系统。若没有使用-d选项,pkgadd在缺省的假脱机目录中查找该报(/var/spool/pkg)。若使用-s选项,就将该包读到假脱机目录而不安装它。

       选项:

-d  device安装或拷贝一个包。device可以是到目录的完整路径名。

pkginst 说明被安装的包实例或实例列表记号all可用来查阅在源介质上的所有可用包。

    32groupaddmkgroup命令

       把新的小组定义添加(建立)给系统

groupadd [-g gid[-0]] groupname

       选项:

-g  gid  对新组的组id。此组id必须是非负的十进制整数,此整数小于在<param.h>主文件中定义的MAXUID

       例如:

groupadd -g $GroupID $GroupName

    注:HPSUN平台使用“groupadd”命令。IBM平台使用“mkgroup”命令。

    增加用户的命令见“五.54 useraddmkuser命令”

    33ln命令

       建立硬链或符号链。

ln [-fs] filename [linkname]

filename连接到linkname。其中filename可以是一个或多个文件名,用户可建立多个file连接到linkname

       选项:

-s   ln将建立一个象征性连接。

    34su命令

       成为特殊用户或其他用户。

su [-][name[arg ......]]

       su允许一个用户在未注销时成为另一个用户。

       选项:

-  完成一个完全的注册。删除除TERM之外的环境中的所有变量,将USER设置为nameHOMESHELL从被替换用户的口令文件中获得,将PATH设置为:/usr/ucb:/bin:/usr/bin,将目录更改为name的本地目录,并告诉shellname.login.profile文件。

-f 完成一个快速的su。如果与C shell一起使用,将阻止C shell去读name.cshrc文件,如果与Bourne shell一起使用,将不支持文件名生成。

        例如:

           执行ln命令和成为sms用户:

su - sms -c "ln -s $SCP_HOME/sms v20"

    35setenv命令

       设置环境变量

       例子:

           设置环境变量INFORMIXDIR的值为$INFORMIX_HOME

setenv  INFORMIXDIR "$INFORMIX_HOME"   

    36repeat命令

       用来执行只有一个固定次数的命令。

       例子:

           在屏幕上显示连字符(-)80

repeat 80 echo ‘-‘

        37getopts命令

        用来解析命令选项。

       用法:

getopts optstring  name[arg...]

       说明:

optstring必须包含使用getopts将识别的选项字母,如果字母右跟随一个冒号,则选项期望有一个变元或变元组,并由空格分开。

每一次调用时,getopts把下一个选项放入shell变量Name中,且在shell变量OPTIND中处理下一个变元的索引;无论是调用shellsehll过程,OPTIND初始化为1

当一个选项需要一个选项变元,getopts把它放置在shell变量OPTARG中。

如果遇到一个非法选项,将把?放入name中。

当遇到选项结束时,getopts将带着一个非0出口状态退出;专用选项—-可以用来确定选项结束的边界。

在缺省状态下,getopts解析位置参数,如果getopts命令行中给出变元(arg...)getopts将解析它们。

实例:

下述的shell程序框架显示如何处理选项ab及选项o的命令变元的:

while getopts abo:c OPTION

do

    case $OPTION in

        a|b)

            FLAG=$OPTION

            ;;

        o)

            ORAG=$OPTARG

            ;;

        /?)

            echo $USAGE

            exit 2

            ;;

    esac

done

shift `expr $OPTIND – 1`   

此代码接收下述任意等价命令:

cmd –a –b -o123 file

cmd –a –b -- –o123 file #将忽略”—-“以后的选项

cmd –ab –o”xxx”  file

cmd –o”xxx” –a –b file

 

38sort命令

把所有命名文件一起排序和合并,并把结果写到标准输出上。如果使用’-‘作为文件名或者没有命名输入文件,则读标准输入。

简单用法:

sort [-dfiMnr][files]

下列选项重写缺省的排序规则:

-d  ”Dictionary”排序,在比较时只人士字母、数位和空格

-f  将下档字符转化成上档字符

-i  忽略不可打印的字符

38kill命令和trap命令

操作系统可以向脚本或命令发出消息,告知它们某个事件的发生,这些事件通常是内存错误、访问权限问题或某个用户试图停止你的进程等等。这些事件称之为信号。它们中的一些可以被shell脚本捕获。

如信号2就表示来自键盘的中断信号,当按下CTRL-C时触发此信号。信号2的名字是SIGINT 2是信号的号码。

注:如果想查看所有信号,可以使用kill -l命令列出所有信号。

发送信号可以使用如下格式:

kill  [-signal no: | signal name ] process ID

在脚本捕获信号的命令的形式如下:

trap  command  signal(s)

   command是捕获到信号后用来处理的函数,需要使用引号扩起。

例如:

trap  ""  2  3       忽略信号23

trap "commands"  2  3    如果捕捉到信号22,则执行相应的commands命令

下面是一个脚本例子,trap 捕获signal 2

#!/bin/sh

# use trap to catch signal 2 (CTRL-C)

# set trap

trap "catch_signal_two"  2

LOOP=0

# catch signal 2

catch_signal_two()

{

    echo "You just hit <CTRL-C>, at number $LOOP"

    echo "I will now exit"

    exit 1

}

# loop

echo "Loop start, you can use CTRL-C to end."

while :

do

    LOOP=`expr $LOOP + 1 `

    echo $LOOP

done

注:当在catch_signal_two函数中不使用exit命令时,while循环中触发以及处理完trap后,while循环还会从打断的地方继续执行。

39.操作系统和数据库检查(IBM)(一):检查核心参数的配置

#ulimit -a

time(seconds)        unlimited

file(blocks)         2097151

data(kbytes)         262144

stack(kbytes)        32768

memory(kbytes)       32768

coredump(blocks)     2097151

nofiles(descriptors) 2000

40.操作系统和数据库检查(IBM)(二):检查时区的配置

#grep TZ /etc/environment

正确的格式为:TZ=BeiJing-8

说明: 

TZ的格式: STDoffset[DST[offset][,rule]]   

STD表示时区,DST表示夏令时;

当地时间加上offset就是UTC时间。rule为夏令时的规则.

41.操作系统和数据库检查(IBM)(三):检查硬件错误

#errpt –d H

如果有输出,则表示有硬件错误。

42.操作系统和数据库检查(IBM)(四):检查硬盘错误

#smitty ssaraid

选择第一项

如果第4列为good,则表示磁盘系统正常。

43.操作系统和数据库检查(IBM)(五):检查交换区的使用情况

#lsps –a

使用率不要超过70%,否则最好重起一把机器

44.操作系统和数据库检查(IBM)(六):检查内存的使用情况

#vmstat  2  50

r  b   avm   fre  re  pi  po  fr   sr  cy  in   sy  cs us sy id wa

0  1 167253 503710   0   0   0   0    0   0 908 2000 519  1  0 98  0

0  1 167253 503710   0   0   0   0    0   0 912 2001 524  2  0 98  0

如果frsr不为0,表示有内存申请操作;pipo不为0,表示有page操作

45.操作系统和数据库检查(IBM)(七):检查系统的运行情况

#topas

可以看到CPU的使用情况,网卡的使用情况,磁盘的使用情况,进程的状态,内存的情况,交换区的情况等。

46.操作系统和数据库检查(IBM)(八):检查文件系统的使用情况

#df k

Filesystem    1024-blocks      Free  %Used    Iused %Iused Mounted on

/dev/hd4            32768        22516    32%     1421     9% /

/dev/hd2          2555904     1310716    49%    39736     7% /usr

/dev/hd9var         32768        12908   61%      263     4% /var

/dev/hd3            32768          2616   93%      293     4% /tmp

说明:    %Used不能超过70

                 %Iused不能超过90%

                 /tellinshare不能少于1G

                 /tellinFree不能少于500M

47.操作系统和数据库检查(IBM)(九):检查文件系统的属性

#mount

node                 mounted     vfs    date             options

-------             ----------  ----  --------         ---------------

/dev/hd4            /             jfs    Jan 07 15:27   rw,log=/dev/hd8

/dev/hd2            /usr         jfs    Jan 07 15:27    rw,log=/dev/hd8

/dev/hd9var        /var          jfs    Jan 07 15:27    rw,log=/dev/hd8

/dev/hd3            /tmp         jfs    Jan 07 15:27    rw,log=/dev/hd8

/dev/tellinlv      /tellin      jfs    Jan 07 15:28    rw,log=/dev/hd8

说明:/tellinshareoptions属性为rw,mind

48.操作系统和数据库检查(IBM)(十):HACMP检查

# /usr/sbin/cluster/clstat

                clstat - HACMP Cluster Status Monitor

                ---------------------------------------------

Cluster: scu_cluster    (177)           Wed Jan  8 10:27:15 TAIST 2003

                State: UP               Nodes: 2

                SubState: STABLE

        Node: win1              State: UP

           Interface: win1_boot (0)             Address: 10.163.144.11

                                           State:   UP

           Interface: win1_tty (1)              Address: 0.0.0.0

                                            State:   UP

        Node: win2              State: UP

           Interface: win2_boot (0)             Address: 10.163.144.13

                                           State:   UP

           Interface: win2_tty (1)              Address: 0.0.0.0

                                           State:   UP

49.操作系统和数据库检查(IBM)(十一):检查数据库的DR状态

对于主机

$ onstat –g ath|grep dr

57      d5bb53d8 d5a2f63c 2    cond wait  drcb_bqf     1cpu        dr_prsend

67      d5cbd670 d5a2fb28 2    sleeping secs: 1        1cpu        dr_prping

68      d5cbda30 d5a30014 2    sleeping secs: 1        1cpu        dr_btsend

 

对备机

$ onstat –g ath|grep dr

 31      d5462030 d52dada0 3    cond wait  netnorm    1cpu       dr_secrcv

 32      d5462678 d52db28c 3    cond wait  drcb_bqf   1cpu       dr_secapply

 33      d5462a38 d52db778 3    sleeping secs: 6        1cpu       dr_secping

 34      d5462df8 d52dbc64 3    sleeping forever        1cpu       dr_btrecv

50.操作系统和数据库检查(IBM)(十二):检查数据库的运行状态

$ onstat –p

Profile

dskreads pagreads bufreads %cached dskwrits pagwrits bufwrits %cached

1653     5839     78992    97.91   31555    503390   1007     0.00

isamtot  open     start    read     write    rewrite  delete   commit   rollbk

112315   9475     17818    22031    0        0        0        0        0

gp_read  gp_write gp_rewrt gp_del   gp_alloc gp_free  gp_curs

0        0        0        0        0        0        0

ovlock   ovuserthread ovbuff   usercpu  syscpu   numckpts flushes

0        0            0        17.51    23.79    5        11

bufwaits lokwaits lockreqs deadlks  dltouts  ckpwaits compress seqscans

855      0        0        0        0        0        10       208

ixda-RA  idx-RA   da-RA    RA-pgsused lchwaits

0        2        1016     1018       69

 

说明:红色部分的数据为0就表示正常,否则需要调整运行参数

$ onstat –g sql

Sess  SQL            Current            Iso Lock       SQL  ISAM F.E.

Id    Stmt type      Database           Lvl Mode       ERR  ERR  Vers

31    -              vpn83200           CR  Wait 5     0    0    7.24

30    -              vpn83200           CR  Wait 5     0    0    7.24

29    -              vpn83200           CR  Wait 5     0    0    7.24

28    -              vpn83200           CR  Wait 5     0    0    7.24

27    -              vpn83200           CR  Wait 5     0    0    7.24

26    -              vpn83200           CR  Wait 5     0    0    7.24

25    -              vpn83200           CR  Wait 5     0    0    7.24

24    -              vpn83200           CR  Wait 5     0    0    7.24

23    -              vpn83200           CR  Wait 5     0    0    7.24

21    -              vpn83200           CR  Wait 5     0    0    7.24

说明:关注是否出现ERR.

51.操作系统和数据库检查(IBM)(十三):数据库检查

$ oncheck –cc

Validating database vpn83200

    Validating systables for database vpn83200

   Validating syscolumns for database vpn83200

    Validating sysindexes for database vpn83200

 

$ oncheck –cR

Validating Informix Dynamic Server reserved pages

    Validating PAGE_PZERO...

    Validating PAGE_CONFIG...

    Validating PAGE_1CKPT & PAGE_2CKPT...

          Using check point page PAGE_2CKPT.

Validating physical log pages ...

Validating logical logs ...

    Validating PAGE_1DBSP & PAGE_2DBSP...

         Using DBspace page PAGE_2DBSP.

    Validating PAGE_1PCHUNK & PAGE_2PCHUNK...

          Using primary chunk page PAGE_2PCHUNK.

    Validating PAGE_1ARCH & PAGE_2ARCH...

          Using archive page PAGE_2ARCH.

 

$ oncheck –cI  iinscp

Validating indexes for vpn83200:vpn83200.lactovlr...

                Index  212_494

Validating indexes for vpn83200:vpn83200.mvpn_phone...

                Index  213_498

                Index mvpn_phone_index2

                Index mvpn_phone_index1

52.操作系统和数据库检查(IBM)(十四):检查数据库的运行日志

$ vi  online.log

主要看Checkpoint的时间和频度,是否有断言错误等

53fsck命令

                   检查和修复文件系统。

                   例如:

fsck   –y   #不需要确认直接检查和修复文件系统。

54useraddmkuser命令

为组添加用户。

useradd -d <HOME目录> -g <所属组> -s /usr/bin/csh -m <用户名>

例如:

如在SUN下创建smpsys用户:

useradd -d /home/smpsys -g sms -s /bin/csh -m smpsys

注:

HPSUN平台用useradd命令,IBM平台使用“mkuser”命令,命令格式为:

mkuser  pgrp=<所属组> home=<HOME目录> shell=/usr/bin/csh <用户名>

54exec命令

1.执行命令和程序来取代当前进程

exec command

当执行完毕后,不能返回调用进程,回返回到调用进程的父进程。

         2.打开和关闭文件描述符

                   用于文件输入输出的exec命令的语法

exec < file     打开’file’以进行读操作,并把进程的标准输入链接到’file’

exec > file     打开’file’以进行写操作,并把进程的标准输出链接到’file’

exec >> file        打开’file’以进行写操作,把进程的标准输出链接到’file’,并把标准输出添加到 ‘file’

exec n<file     打开’file’以进行读操作,并给它分配文件描述符’n’

exec n>file     打开’file’以进行写操作,并给它分配文件描述府’n’

exec n<<tat…tag 打开一个here文档(位于<<’tag’’tag’之间的数据)以进行读操作,并给它分配文件描述符’n’

exec n>>file        打开’file’以进行写操作,给它分配文件描述符’n’,并把数据添加到’file’尾部

exec n>&m       ’m’复制到’n’;任何到文件描述符为’n’的文件的数据也会被发送到文件描述符为’m’的文件

exec <&-        关闭标准输入

exec >&-        关闭标准输出

exec n<&-   关闭链接到标准输入的描述符为’n’’file’

exec n>&-   关闭链接到标准输出的描述符为’n’’file’

         当在命令行执行exec < sample 命令时,它把当前的shell的标准输入链接到sample文件.当在一个脚本里执行时,该命令把脚本的标准输如重定向到sample文件. 如果要恢复,需要执行exec </dev/tty命令把标准输入重新链接到终端.

54tr命令

         小写到大写

echo   $var  |  tr  “[a-z]”  “[A-Z]”

echo   $var  |  tr  “[:lower:]”  “[:upper:]”

         大写到小写

echo   $var  |  tr  “[A-Z]”    “[a-z]” 

echo   $var  |  tr  “[:upper:]”  “[:lower:]”

六.杂项

1setenv PATHset path = (....)

       解答:

        set path仅仅作用于当前的shellsetenv也对子shell起作用。

       csh中使用setenv来设置环境变量。

        ksh中使用export来设置环境变量。

csh:

    setenv  ENV_NAME   ENV_VALUE

ksh

    export  ENV_NAME=ENV_VALUE

也可以分步:

    ENV_NAME=ENV_VALUE

    export ENV_NAME

2awk中输出单引号

echo "a b c" |awk '{print $1 单引号 $2  单引号 $3}'

我要给b加单引号,输出成下面格式:

a 'b' c

解答:

echo "a b c"|awk '{printf("%s %c%s%c %s/n",$1,39,$2,39,$3)}'

3awkread找出文件行字符数大于80的行

方法一:使用awkNR

awk '

{

line_len=length

if (line_len >80)

print NR":"line_len

}' <$1

注:若length函数不加参数,则表示处理当前行

方法二:使用read,循环处理

while read line

do

    count=`echo $line|wc -C`

    countnum=`expr $count - 1`

    if [ $countnum -gt 80 ]; then

        echo "$linecount: ($countnum) $line"

    fi

done < $1

4shell脚本程序中的用户切换:

切换到另一个用户,执行几个操作然后退出来,整个过程不退出脚本执行

解答:

su -bin -c command arguments

5shell中删除文件且不显示输出信息和出错信息

解答;

rm ${HOME}/bin/.filesize > /dev/null 2>&1

>为重定向符号,2>&1表示标准错误输出定向导标准输出,又由于标准输出被定向到/dev/null,所以两者都被定向导/dev/null

6shell变量赋初值时存在特殊字符

以下程序无法正常运行:

name=”test”

pwd=”$google”

ftp -in $1 <<FTP_CMD

user $name $pwd

ls

bye

FTP_CMD

原因是$是特殊字符。解决方法,使用单引号

pwd=’$google’

建议:字符串赋初值均采用单引号

7sed的参数串中存在/特殊字符

           需要把 /export/home/mywork 转换为 //export//home//mywork

先构造转化如下:

echo "/export/home/mywork" | sed "s/g"

bshksh下不能运行,在csh下可正常运行。

原因是对sed的表达式的解析不能完成。解决方法,使用单引号

echo "/export/home/mywork" | sed 's/g'

建议:对sed的表达式均采用单引号

    8find在一个目录下找包含一个字符串的所有文件

find ./ -name "*.sh" | xargs grep "set"

find . -name "*.sh" -exec grep -l "set" {} /;

9shell中确定一个文件的存在,文件ins_billdb

if [ ! -f $INSTALL_PATH/ins_billdb ]; then

10read的参数与实际域的个数不同

read只读取一行的文本,当read的参数多于实际域个数时,多余的参数为空,不会读取到下一行;当read的参数少于实际域个数时,最后一个参数的值包含剩下所有域。

例如:

文件内容:1  2 

使用    read  arg1  arg2   arg3读取时,arg3为空。

使用 read  arg1读取时, arg11  2

    11grep获取主机名和IP地址

    方法一.从host文件获取

##############################################

#    name : get_host_info

#    description: get host name and ip address

#    input:   N/A

#    output:  HostName , HostIP

#    return:  0 –- get successfuly

#              others --  get failure

##############################################

get_host_info()

{  

    HostName=`hostname`

    #过滤纯注释行(以#开头或者以 空格+#开头的行),

    #然后过滤127.0.0.1,获取本机的ip地址

     HostIP=`cat /etc/hosts|grep -v "^[ ]*/#" | grep -v 127.0.0.1 | grep $HostName | awk '{print $1}'`

    if [ $? -ne 0 ];then

        echo "Error! can't get Host IP"

        return  1

    fi 

    if [ $? –eq 0 ]; then

        return 0;

    else

        return 1;

     fi

 }

方法二.从ifconfig获取

##############################################

#    name : get_host_info

#    description: get host name and ip address

#    input:   N/A

#    output:  HostName , HostIP

#    return:  0 –- get successfuly

#              others --  get failure

##############################################

get_host_info()

{  

    #得到ip地址所在行

    ip=`ifconfig -a | grep [1-9][0-9]/{0,2/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}" | awk '{print $2}'`

    #提取ip地址

    ip=`echo $ip | awk '{print $2}'`

    is_ip_address $ip

    if [ $? –eq 0 ]; then

        return 0;

    else

        return 1;

     fi

}

    注:is_ip_address函数见“六.13 确定字符串是否是ip地址”

12grep确定变量不是数字

       见“31iTELLIN示例十五:判断一个字符串是否是整数”

13.确定字符串是否是ip地址

##############################################

#    name : is_ip_address

#    description: judge whether the string

#                    is a ip address

#    input:   string

#    return:  0 –- is ip address

#              others --  not ip address

##############################################

is_ip_address()

{

TmpValue=$1

nCount=`echo "$TmpValue" |grep –c  [1-9][0-9]/{0,2/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}/.[0-9]/{1,3/}'`

if [ 1 –eq $nCount ]; then

    # remove the char ‘.’ from $TmpValue

    TmpValue="`echo $TmpValue | sed 's//./ /' | sed 's//./ /' | sed 's//./ /'`"

    for i in $TmpValue

    do

         if [ "$i" -gt 255 ]; then

             #echo "Error! $TmpValue is not a IP address!"

             return 1

         fi

    done

     return 0

else

    #echo "Error! $TmpName is not a IP address!"

    return 1

fi

}

    14grep列出某个用户的所有进程:

USER_NAME

ps -ef | grep "^[ ]*$USER_ NAME"

        grep查找以0到多个空格和用户名开头的行。

15grepawk列出某个目录下的一级子目录

DIR=$1

ls -l $DIR | grep '^[ ]*d/.*' | awk '{print $9}'

ls –l列表的第九项为文件名。如果不加入awk的过滤,则打印子文件夹详细信息。

16.用printf将一个数打印成逗号分隔的形式

    以下为awk中的程序。

 

函数名:  int_add_comma

功能    将传入的整数转化为每N位加一个逗号形式的字符串。

参数   

    num    : 需要被转化的整数

    ret    : 存贮转化以后的字符串,空间由调用者提供

    N      : 间隔位数

返回值: 

    0  --转换正常,结果存放在ret中。

    -1 --转换失败,传入参数不符合要求。

例子:

    调用:

    char buf[10] = "";

    nret = int_add_comma(1234,buf,3);

       返回:

          nret=1

          buf="1,234" 

*/

int int_add_comma(long num,char *ret, int N)

{

    char buf[10] = "";

    char *p, *q;

    int i, j, ncount, nleft;

    if (ret == NULL || N <= 0 )

        return -1;

 

    sprintf(buf, "%u", num);

    ncount = strlen(buf) / N;

    nleft  = strlen(buf) % N;

   

    for (p=buf,q=ret,i=0; i<nleft; i++)

        *q++ =  *p++;

    if (nleft > 0)

        *q++ = ',';

 

    for (i=0; i<ncount; i++)

    {

        for (j=0; j<N; j++)

            *q++ = *p++;

        if (i < ncount-1)

            *q++ = ',';

    }

    *q = '/0';

    return 0;

}

   

17iTELLIN示例一:在ksh中使用数组

a) 初始化数组函数:

#!/usr/bin/ksh

sub_init_var()

{

    HOST_NAME[0]=""             #Save var name array

    HOST_VALUE[0]=""            #Save var value array

    HOST_COMMENTS[0]=""         #Save var commentS array

    HOST_TYPE[0]=""             #Save var type array

    HOST_COUNT=0                #Save array element Count

}

注:其中HOST_NAME等为数组,HOST_COUNT为全局的HOST个数,虽然是在sub_init_var中声明,但是变量作用域是全局的。

b) 循环给数组赋值,取数组元素个数,访问数组元素、数组元素长度

#!/bin/ksh

datalist=`ls -l | awk '{print $9}'`

index=0

for j in $datalist

do

    datalist[$index]=$j

    let index+=1 #或者 index=`expr $index + 1`

done

index=0

# ${#datalist[@]}数组元素个数

while [ $index -lt ${#datalist[@]} ]

do

      # ${datalist[index]}数组元素

      # ${#datalist[index]}数组元素长度

    echo “${datalist[index]} length is ${#datalist[index]}

    let index+=1 #或者 index=`expr $index + 1`

done

18iTELLIN示例二:从文件中读取参数:

       文件存放格式:

[HOST]

g_Node1_Host    itellin1       #Node 1 host name

g_Node2_Host    itellin2       #Node 2 host name

g_ClusterName   itellin        #Cluster name

[DEVICE]

SMC_IP 10.76.137.101    #Service Manager Center IP

SMC_LISTEN_PORT 5060    #Service Manager Center Listen portal

Set_FireWall NO          #Portal FireWall Set

FireWallIP   10.76.137.156  #Portal FireWallLogic host IP

... ...

文件读取函数:

###########################################################

# 函数:read_var

# 目的:从全局配置文件中读取变量值

# 方法:

# 输入:全局配置文件名

# 输出:全局配置文件中的变量值

# 限制:

###########################################################

read_var()

{

    #参数个数是否是一个

    if [ $# -ne 1 ]; then

        echo "Error usage!"

        exit 1

    fi

    CfgFile=$1

    #参数所代表的配置文件是否存在

   if [ ! -f $CfgFile ]; then

       sub_echo_log "File $CfgFile does not exist!"

        exit 1

     fi 

   echo "/nread configuring file, wait..."

 

   #读取 NAME  VALUE  COMMENT

   while read VarName VarValue VarTemp

   do

      #如果是读取 HOST 段的信息

      if [ "1" -eq "`echo "$VarName" | grep -c '/[HOST/]'`" ]; then

         while read VarName VarValue VarTemp

         do

            if [ "-$VarName" = "-" ]; then

                continue

           #如果是 [xxxx]形式的文本

             elif [ "1" -eq "`echo "$VarName" | grep -c '/[.*/]'`" ]; then

                break

             else

                HOST_NAME[HOST_COUNT]="$VarName"

                #如果是注释(以#开头)

                 if [ "1" -eq "`echo "$VarValue" | grep -c '^#.*'`" ]; then

                    HOST_VALUE[HOST_COUNT]=""

                    HOST_COMME[HOST_COUNT]=""

                 else

                    HOST_VALUE[HOST_COUNT]="$VarValue"

                    HOST_COMME [HOST_COUNT]="$VarTemp"

                 fi

                 ((HOST_COUNT=HOST_COUNT+1))

              fi

           done

       fi

       #如果是读取 DEIVCE 段的信息

       #格式同HOST段的读取

        ... ...

       continue  

   done < $CfgFile

   sub_echo_log "read configuring file $SrcFile ok"

}

 

19iTELLIN示例三:包含其它脚本文件

    使用操作符.包含另一个脚本文件package.cfg

.  $INSTALL_PATH/package.cfg 

其中package.cfg文件内容如下:

    #压缩文件名

    SCP_CMPD_FILE="iSCP_INSTALL.tar.Z"

    SMP_CMPD_FILE="iSMP_INSTALL.tar.Z"

    MML_CMPD_FILE="MMLSERVER_install.tar.Z"

    WMAS_CMPD_FILE1="WmasBin.tar.Z"

    WMAS_CMPD_FILE2="WmasRunEnv.tar.Z"

    ... ...

20iTELLIN示例四:初始化一个临时文件供使用

##############################################

#    name : sub_initfile

#    description: initialize a temp file for use

#    input:   temp file name

#    return:  N/A

##############################################

sub_initfile()

{

  FileName="$*"

  if [ -f $FileName ]; then

    rm -f $FileName

  fi

  touch $FileName

  chmod 666 $FileName

}

初始化一个临时文件,将df输出结果写入临时文件,显示临时文件内容

    sub_initfile $TmpFile

    df -k > $TmpFile

    if [ "$?" != "0" ]; then

        sub_echo_log "Error! Check file system failure!"

        exit 1

    fi

    echo "/n*************** file system BEGIN ***************/n"

    cat "$TmpFile"

    echo "/n** ************* file system END ***************/n"

 

21iTELLIN示例五:分解字符串

字符串为"set shmsys:shminfo_shmmax=256000000",为函数参数

分解代码如下:

system_set_value()

{

    TmpInf=$*

    #得到TmpInf1="256000000"

    TmpInf1="`echo $TmpInf | awk -F= '{print $2}' | awk '{print $1}'`"

    #得到TmpInf="set shmsys:shminfo_shmmax"

    TmpInf="`echo $TmpInf | awk -F= '{print $1}'`"

    #得到TmpInf2="shminfo_shmmax"

    TmpInf2="`echo $TmpInf | awk -F: '{print $2}' | awk '{print $1}'`"

    #得到TmpInf="set shmsys"

    TmpInf="`echo $TmpInf | awk -F: '{print $1}'`"

    #得到TmpInf3=" shmsys"

    TmpInf3="`echo $TmpInf | awk '{print $2}'`"

    #得到TmpInf4="set"

    TmpInf4="`echo $TmpInf | awk '{print $1}'`"

}

22iTELLIN示例六:替换配置文件中的值

    配置文件中的配置参数被设置参数取代。

    如配置文件为$TmpFile,里面有一行为

set shmsys:shminfo_shmmax=256000000

shell代码中的缺省配置为

set shmsys:shminfo_shmmax=199000000

    在得到用户许可以后,使用缺省配置代替$TmpFile中的值,代码如下:

#从缺省配置行得到变量TmpInf1,TmpInf2,TmpInf3,TmpInf4(见上例)

SetInf="set shmsys:shminfo_shmmax=256000000"

system_set_value  $SetInf

#得到配置文件的拷贝

cat "/etc/system" > $TmpFile

#如果配置文件中有相应的配置行

if [ "1" -eq `cat $TmpFile | grep -v "^[    ]*/*" | grep $TmpInf4 | grep $TmpInf3 | grep -c $TmpInf2` ]; then

    #得到配置文件的配置行

    MyInf=`cat $TmpFile | grep -v "^[   ]*/*" | grep $TmpInf4 | grep $TmpInf3 | grep $TmpInf2`

    #保存缺省配置的数值

    OldTmpInf1="$TmpInf1"

    #从文件配置行得到变量TmpInf1,TmpInf2,TmpInf3,TmpInf4

    system_set_value $MyInf

    #若文件配置行中的数值和缺省配置行的数值不同

    if [ "$OldTmpInf1" != "$TmpInf1" ]; then

      echo "Warning! Your value is $TmpInf1, but default value is $OldTmpInf1."

       sub_echo_read "Are you want to replace it? (y/n):/c"

       if [ "$SurCho" = "n" ]; then

          sub_echo_log "Warning! $MyInf was not default value."

       else

        #使用缺省配置行替换配置文件中的配置行,并写回到配置文件中

          cat $TmpFile | sed "s/$MyInf/$SetInf/" > $TmpFile1

          cp $TmpFile1 $TmpFile

          sub_echo_log "OK! $TmpInf1 was replaced with $OldTmpInf1"

      fi

    fi                     

else  #若配置文件中不存在相应的配置行

    sub_echo_log "Error! not $SetInf"

    #将缺省配置行添加到配置文件中

    echo "$SetInf" >> $TmpFile

    sub_echo_log "OK! Add $SetInf"

fi

 

23iTELLIN示例七:取得字符串的长度 ##############################################

#    name : get_length  

#    description: get the length of string

#    input:   string

#    return:  lenght of string

##############################################

get_length()

{

    return `echo $1 | awk '{print length($0)}'`

}

取得字符串$0的长度,用以判断其最后一个字符是否是字符/,如果是,则删除此字符

get_length $FileDir

StrLength=$?

if [ "/" = "`echo $FileDir | cut –c $StrLength`" ]; then

    ((StrLength=StrLength-1))    #此行sh不支持,应改用expr

    FileDir="`echo $FileDir | cut -c1-$StrLength`"

fi

 

24iTELLIN示例八:用另外的文件作为函数库

         主程序在autoinstall文件中执行,有一个解压缩的功能由另一个文件file_uncmp实现,则在autoinstall文件中调用如下:

#调用file_uncmp文件中的函数解压缩

$IN_PATH/file_uncmp  $CmpdFile  $IN_PATH/mend_check_dir

    file_uncmp文件中:

#!/bin/ksh

file_uncmp()

{

    ......

}

if [ $# -ne 2 ]; then

    echo "Error usage!"

    exit 1

fi

file_uncmp $1 $2

25iTELLIN示例九:解压缩文件到一个目录

###########################################################

# 函数:file_uncmp

# 目的:压缩文件解压

# 方法:

# 输入:压缩文件名,解压路径

# 输出:解压后的目录和文件

# 限制:

###########################################################

file_uncmp()

{

    #$1为压缩文件的全路径

    CmpdFile=$1

    #$2为目录

    UncmpPath=$2

    #判断解压路径是否正确

    CurDir="`pwd`"

    if [ "$UncmpPath" != "$CurDir" ]; then

        echo "Error uncompress path $UncmpPath!"

        exit 1

    fi

    #判断解压文件是否存在

    if [ ! -f $CmpdFile ]; then

        echo "File $CmpdFile not find."

        exit 1

    fi

    #删除解压缩目的目录中的所有文件。

    rm -f $UncmpPath/*.tar.Z

    rm -f $UncmpPath/*.tar

    rm -f $UncmpPath/*.CPI

    rm -f $UncmpPath/*.war

    echo "/nCopy file, Please wait......"

    #将压缩文件拷贝到目录目录中(判断操作是否成功)

    cp $CmpdFile $UncmpPath

    if [ "$?" -ne 0 ]; then

        echo "Can not access file $CmpdFile"

        exit 1

    fi

    SrcfType=false

    echo "/nUncompress file. Please wait......"

    #判断是否存在tar.Z文件

    ls *.tar.Z > /dev/null 2>&1

    if [ "$?" -eq 0 ]; then

        SrcFile="`ls *.tar.Z`"

        SrcfType=true

        Opts="`uncompress -f $SrcFile`"

        Rtns=$?

        if [ $Rtns -ne 0 ]; then

            echo "$Opts"

            echo "Uncompress file $SrcFile failed!"

            exit 1

        fi

    fi

    #判断是否存在tar文件

    ls *.TAR > /dev/null 2>&1

    if [ "$?" -eq 0 ]; then

        SrcFile="`ls *.TAR`"

        SrcfType=true

        Opts="`tar xvf  $SrcFile`"

        Rtns=$?

        if [ $Rtns -ne 0 ]; then

            echo "$Opts"

            echo "TAR  file $SrcFile failed!"

            exit 1

        fi

        rm -f $UncmpPath/*.TAR

        exit 0

    fi

    ls *.tar > /dev/null 2>&1

    if [ "$?" -eq 0 ]; then

        SrcFile="`ls *.tar`"

        SrcfType=true

        Opts="`tar xvf $SrcFile`"

        Rtns=$?

        if [ $Rtns -ne 0 ]; then

            echo "$Opts"

            echo "Tar file $SrcFile failed!"

            exit 1

        fi

    fi

    ls *.war > /dev/null 2>&1

    if [ "$?" -eq 0 ]; then

        SrcFile="`ls *.war`"

        SrcfType=true

        Opts="`jar xvf $SrcFile`"

        Rtns=$?

        if [ $Rtns -ne 0 ]; then

            echo "$Opts"

            echo "Tar file $SrcFile failed!"

            exit 1

        fi

    fi

    ls *.CPI > /dev/null 2>&1

    if [ "$?" -eq 0 ]; then

        SrcFile="`ls *.CPI`"

        SrcfType="TRUE"

        Opts="`cpio -icvumd < $SrcFile`"

        Rtns=$?

        if [ $Rtns -ne 0 ]; then

            echo "$Opts"

            sub_echo_log "Cpio SCP source file $SrcFile failed!"

            exit 1

        fi

    fi

    if [ "$SrcfType" = false ]; then

        echo "Format of source file $CmpdFile is not known!"

        exit 1

    fi

    echo ""

    echo "Uncompress file completed."

   

    rm -f $UncmpPath/*.tar.Z

    rm -f $UncmpPath/*.tar

    rm -f $UncmpPath/*.CPI

}#end of file_uncmp()

 

 

26iTELLIN示例十:判断操作是否成功

       拷贝:

cp $CmpdFile $UncmpPath

if [ "$?" -ne 0 ]; then

    echo "Can not access file $CmpdFile"

    exit 1

fi

       取得主机名和IP地址:

#获取主机名

HostName=`hostname`

#过滤纯注释行(以#开头或者以 空格+#开头的行),

#然后过滤127.0.0.1,获取本机的ip地址

HostIP=`cat /etc/hosts|grep -v "^[ ]*/#"|grep -v 127.0.0.1|grep $HostName|awk '{print $1}'`

if [ $? -ne 0 ];then

  sub_echo_log "Error! can't get Host IP"

  exit 1

fi

    检测系统:

echo "Your SunOs version is `uname -r`"

if [ "$?" != "0" ]; then

    sub_echo_log "Error! Check solaris version failure!"

    return

fi

    一些要判断操作结果是否成功的命令:

    cpcatdflspkginfoifconfigpingunamemkdirpkgaddsucdnetstatgroupaddgroupdel

27iTELLIN示例十一:封装创建一个组的函数

    以下函数创建一个组,调用:group_creat "informix" "101

###############################################################

# 函数:group_creat

# 目的:创建组

# 方法:

# 输入:组名、组ID

# 输出:组

# 限制:

###############################################################

group_create()

{

    #如果存在此组或者存在和组ID相同的组,均删除,然后重新创建一个组

    if [ ! -f "/etc/group" ]; then

        echo "File /etc/group does not exist!"

        exit 1

    fi

    #$1为组名,$2为组ID   

    GroupName=$1

    GroupID=$2

    GroupFlag=false

    while read LineContent

    do

        OldGroupName="`echo "$LineContent" | awk -F: '{print $1}'`"

        if [ "$GroupName" = "$OldGroupName" ]; then

            GroupFlag=true

            break

        fi

    done < "/etc/group"

    if [ "$GroupFlag" = true ]; then

        groupdel $OldGroupName

        sub_echo_log "Del group $OldGroupName existed."

    fi

    GroupFlag=false

    while read LineContent

    do

        OldGroupID="`echo "$LineContent" | awk -F: '{print $3}'`"

        if [ "$GroupID" = "$OldGroupID" ]; then

            OldGroupName="`echo "$LineContent" | awk -F: '{print $1}'`"

            GroupFlag=true

            break

        fi

    done < "/etc/group"

    if [ "$GroupFlag" = true ]; then

        exec_Cmd "groupdel $OldGroupName"

        sub_echo_log "Del group $OldGroupName existed for the same group ID."

    fi

    exec_Cmd "groupadd -g $GroupID $GroupName"

    sub_echo_log "OK! Creat group $GroupName."

}

28iTELLIN示例十二:封装创建一个用户的函数

##################################################################

#函数:user_creat

# 目的:自动创建用户

# 方法:

# 输入:用户名,用户ID,组名,主目录

# 输出:用户

# 限制:

#################################################################

user_creat()

{

    if [ ! -f "/etc/passwd" ]; then

        echo "File /etc/passwd does not exist!"

        exit 1

    fi

    UserName=$1

    UserID=$2

    GroupName=$3

    HomePath=$4

    UserFlag=false

    while read LineContent

    do

        OldUserName="`echo "$LineContent" | awk -F: '{print $1}'`"

        if [ "$UserName" = "$OldUserName" ]; then

            UserFlag=true

            break

        fi

    done < "/etc/passwd"

    if [ "$UserFlag" = true ]; then

        echo "Delete old files, wait......"

        #删除主目录中的所有文件

        rm -r $HomePath/* >> /dev/null 2>&1 

        #删除用户

        userdel  $OldUserName               

        sub_echo_log "Del user $OldUserName existed."

    fi

    UserFlag=false

    while read LineContent

    do

        OldUserID="`echo "$LineContent" | awk -F: '{print $3}'`"

        if [ "$UserID" = "$OldUserID" ]; then

            OldUserName="`echo "$LineContent" | awk -F: '{print $1}'`"

            UserFlag=true

            break

        fi

    done < "/etc/passwd"

    if [ "$UserFlag" = true ]; then

        #删除主目录中的所有文件

        su - $OldUserName -c "rm -r *; rm -r .*" >> /dev/null 2>&1 

        #删除用户

        userdel $OldUserName                       

        sub_echo_log "Del user $OldUserName existed for the same user ID."

    fi

    useradd -u $UserID -d $HomePath -g $GroupName -s /bin/csh -m -k /etc/skel $UserName

    chgrp $GroupName $HomePath

    chown $UserName $HomePath

    #如果是sms用户则建到scp用户的链接

    if [ "$UserName" = "sms" ]; then

        rm $SMS_HOME/v20 > /dev/null 2>&1

        su - sms -c "ln -s $SCP_HOME/sms v20"

        if [ "$?" != "0" ]; then

            sub_echo_log "Error! Creat sign link v20 failure."

        fi

    fi

    sub_echo_log "OK! Creat user $UserName."

    echo "Please input user $UserName password."

    passwd $UserName

}

29iTELLIN示例十三:判断一个字符串是否是正整数

##############################################

#    name : is_positive_integer

#    description: judge whether the string is a positive integer

#    input: string

#    output:    0--is positive integer  

#                 others--not a positive integer

##############################################

is_positive_integer()

{

Str=$1

        # trim the left and right space

        Str=`echo $Str`

    # is null string ?

    if [ "-${Str}" = "-" ]; then

        #echo "null str"

        return 1

    fi

    # is equal zero

    if [ "-${Str}" = "-0" ]; then

        #echo "equal zero"

        return 1

    else

        # try to remove number characters from the string

        nRes=`echo ${Str} | sed 's/[0-9]*//g'`

        # get the length of the remained string

        nLen="`echo ${nRes} | awk '{print length($0)}'`"

        # if has characters remained

        if [ nLen -ne 0 ]; then 

            #echo "contain others characters or less than zero"

            return 1

        else

            #echo "is positive integer"

            return 0

        fi

    fi

}

 

30iTELLIN示例十四:判断当前用户是否有root权限

#检查是否为root用户

Opts=`id | grep '(root)' | grep -c 'uid=0'`

if [ ${Opts} -eq 0 ]; then

    echo "Error! autoinstall must run with root user."

    exit 1

fi

 

31iTELLIN示例十五:判断一个字符串是否是整数

##############################################

#    name : is_integer

#    description: judge whether the string is a integer

#    input: string

#    output:    0--is integer

#                 others--not a positive integer

##############################################

is_integer()

{

    Str=$1

   # trim the left and right space

   Str=`echo $Str`

   if [ "-$Str" = "-" ]; then

   #echo "null str"

       return 1

   fi

   # try to remove number characters from the string

   nRes=`echo ${Str} | sed 's/^/([+-]*/)[0-9][0-9]*//g'`

   # get the length of the remained string

   nlen="`echo ${nRes} | awk '{print length($0)}'`"

   # if has characters remained

   if [ "-$nlen" != "-0" ]; then

   # echo "contain others characters or less than zero"

       return 1

   else

   #echo "is a integer"

       return 0

   fi

}

32iTELLIN示例十六:删除某个文件夹下若干天以来未改动的文件

        ##############################################

        #    name : rm_file_ago 

        #    description: rm files days ago

        #    input:   directory   

        #              ndays :  days ago

        #    return:  N/A

        ##############################################

        rm_file_days_ago()

        {

            list=`find $1 -mtime +$2 -print`

            for file in  $list

            do

                echo "rm $file"

            rm -fr $file

            done

        }

33.各种Unix环境对ksh的影响:

(1) IBM$0的支持:

IBM机器不支持函数中使用$0代替函数名,它的$0总是代表sh文件的名字,所以不能使用$0来代表函数名.

(2) SUNawk的支持:

   awk-v可以将shell中的变量传入到awk内部变量,但是SUNawk不一定支持这个语法,如果要确保支持本语法,可以使用

/usr/xpg4/bin/awk -v key="$key_name" -v value="$svalue"

要注意两点:1.路径   2.-v和变量之间有空格(普通awk没有空格)

(3) SUNgrep的支持:

   grep –E 的扩展支持在SUN下必须使用:

/usr/xpg4/bin/grep -E 'Archive| [0-9][0-9]:[0-9][0-9]:[0-9][0-9] '

(4) ~的使用

   一般使用~iinscu即可得到iinscuhome目录.但是当把iinscu保存在变量中时, user_name=”iinscu”, 无法使用 ~$user_name得到iinscuhome路径.可以使用:

eval “home=~$user_name”

或者使用$user_name/etc/passwd中查找:

home=`cat /etc/passwd | grep “^${user_name}:” | awk ‘{print $6 }’`

(5) su 某个用户并执行某个sh,输出到/dev/null.

    su – informix –c “ls  -l >/dev/null 2>&1 “ >/dev/null 2>&1

   sh,csh下会出错,需要指定为ksh

    su – infomix –c “ ksh =-c /” ls –l >/dev/null 2>&1 /” “>/dev/null 2>&1

   csh下可能会提示你 不匹配, 需要将当前sh改成ksh.脚本中需要指定为ksh.

34set 使用注意点:

set $str

        $str为空时,会打印出所有的变量,所以在执行操作前要检查$str是否为空.或者使用set “$str”

35.判断对端节点的文件是否存在:

count=`remsh infox_2 ls /tmp/abc 2>/dev/null | wc -l`

 if [ $count -eq 0 ]; then

       echo "not find"

   else

    echo "find"

 fi

36awksplit函数的使用:

#! /bin/awk

BEGIN {

    record="abc#def#ghi";

    split(record,myarray,"#");

}

END { for (i in myarray) {printf myarray[i]} };

 

$ awk -f aa.awk /dev/null

37.统计字符串在文件中出现的次数:

注意:SUN,其中的grep 要使用  /usr/xpg4/bin/grep, awk要使用 /usr/xpg4/bin/awk, 详细情况请参见本章33.

################################################################# 函数名: count_str_in_file

# 目的:统计字符串在文件中出现的次数

# 方法:

# 输入:

#       1. file name    : 要查找的文件的名字

#       2. key word     : 要查找的关键字

#       3. match case   : 是否区分大小写, 1 --区分 , 0 --不区分

#       4. math whole word only :是否整字匹配,1--整字匹配 ,0--不整字匹配

# 输出:

#       g_total_num 变量存放统计的次数

# 返回值:

#       0 --成功 ,

#       1 --参数数目不正确

#       2 --文件不存在

#       3 --参数类型不合法

################################################################

count_str_in_file()

{

        typeset func_name="count_str_in_file"

        typeset file="$1"

        typeset keyword="$2"

        typeset match_case="$3"

        typeset math_whole_word="$4"

        typeset exp_str=""

        typeset nums=""

        typeset n=""

        typeset total=""

typeset os_type=""

        typeset new_grep=""

        typeset new_awk=""

 

        if [ $# -ne 4 ]; then

                echo "parameters isn't 4"

                return 1

        fi

        if [ ! -f "$file" ]; then

                echo "can't find the file:$file"

                return 2

        fi

        if [ "$match_case" != "1" -a  "$match_case" != "0" ]; then

                echo "match_case parameter invalidate:$match_case"

                return 3

        fi

        if [ "$math_whole_word" != "1" -a  "$math_whole_word" != "0" ]; then

                echo "math_whole_word parameter invalidate:$math_whole_word"

                return 3

        fi

 

        # 系统兼容

        new_grep="grep"

        new_awk="awk"

        os_type=$(uname -s)

        if [ "$os_type" = "SunOS" ]; then

             new_grep="/usr/xpg4/bin/grep"

             new_awk="/usr/xpg4/bin/awk"

        fi

 

        # 转义keyword中的特殊字符

        #  特殊字符:$ . ' " * [ ] ^ | / + ?

        # $

        keyword=$(echo $keyword | sed 's//$///$/g')

        # .

        keyword=$(echo $keyword | sed 's//.///./g')

        # "

        keyword=$(echo $keyword | sed 's/"///"/g')

         # *

        keyword=$(echo $keyword | sed 's/*///*/g')       

        # [

        keyword=$(echo $keyword | sed 's//[///[/g')

        # ]

        keyword=$(echo $keyword | sed 's//]///]/g')

        # ^

        keyword=$(echo $keyword | sed 's//^///^/g')               

        # |

        keyword=$(echo $keyword | sed 's//|///|/g')                       

        # /

        keyword=$(echo $keyword | sed 's/g')                       

        # +

        keyword=$(echo $keyword | sed 's//+///+/g')                       

 

        if [ "$match_case" = "1" ] ;then        # 区分大小写

            exe_cmd="tee"

            if [ "$math_whole_word" = "1"  ]; then  # 整字匹配

              exp_str="(^[    ]*$keyword[     ])|(^[ ]*$keyword[     ]*$)|([     ]$keyword[ ])|([     ]$keyword[ ]*$)"

            else

                exp_str="$keyword"

            fi

        else

            exe_cmd="tr '[:upper:]' '[:lower:]' "

            keyword="`echo $keyword | tr '[:upper:]' '[:lower:]'`"

            if [ "$math_whole_word" = "1"  ]; then  # 整字匹配

              exp_str="(^[    ]*$keyword[     ])|(^[ ]*$keyword[     ]*$)|([     ]$keyword[ ])|([     ]$keyword[ ]*$)"

            else

                exp_str="$keyword"

            fi

        fi

 

        echo "debug keyword:$keyword"

        echo "debug exp:--$exp_str--"

 

        nums=$(cat $file | $exe_cmd |  $new_grep -E "$exp_str" | $new_awk -v t="$keyword" '{

           str=$0;

           n=index($0,t);

           keylen=length(t);

 

           ncount=0;

           while(n != 0)

           {

               ncount++;

               str=substr(str,n+keylen);

               n=index(str,t);

           }

           print ncount;

         }')

        

        total=0

        for n in $nums

        do

           ((total=total+n))

        done

        g_total_num=$total

}

 

# 查找非字母数字等字符时,使用非全字匹配

count_str_in_file  inst_app.sh  '/"'  "0"  "0"

echo "$g_total_num"

 

count_str_in_file "inst_app.sh" "/["  "1"  "0"

echo "$g_total_num"

 

count_str_in_file "inst_app.sh" "if"  "1"  "1"

echo "$g_total_num"

 

count_str_in_file "inst_app.sh"  "/*"  "0"  "0"

echo "$g_total_num"

38.如何进行精确匹配:

除了特殊平台使用特殊的选项外(sun 平台对grep 使用 w选项)

以下方法可以通用并且扩展:

精确匹配需要满足以下条件(暂不考虑由于标点符号分隔导致"hello world" 也要匹配到hello这种情况,如果要匹配这种情况,需要添加 前/后条件并同时修改 s_nume_num):

keyword: 开头+n个空白(n>=0):    ^[ ]*

keyword: 1个空白:               [ ]

keyword: n个空白+换行(n>=0):     [ ]*$

keyword: 1个空白:                [ ]

组合后得到n个单个的条件,使用 | 符号组合这些条件:

 

key=error

s[0]="^[    ]*"    # []中是一个Blank Space和一个TAB,下同

s[1]="[     ]"

e[0]="[     ]*$"

e[1]="[     ]"

s_num=2

e_num=2

 

# combo the single expression statement

i=0

n=0

while [ $i -lt $s_num ]

do

    j=0    

    while [ $j -lt $e_num ]

    do

        exp[n]="${s[i]}${key}${e[j]}"

        ((j=j+1))

        ((n=n+1))

    done

    ((i=i+1))

done

 

# combo the regular express

reg_exp=0

k=0

while [ $k -lt $n ]

do

    if [ $k -eq 0 ]; then

        reg_exp="(${exp[k]})"

    else

        reg_exp="$reg_exp|(${exp[k]})"

    fi

    ((k=k+1))

done

grep -E "$reg_exp"  $file_name

:

1.   []中是一个Blank Space和一个TAB

         2.   sun下需要使用 /usr/xpg4/bin/grep 代替 grep

 

 

39.给系统登录的用户发消息

if [ $(uname) = “AIX” ]; then

OS=”AIX”

else

OS=”OTHER”

fi

list=$(who | awk '{ print $2 }')

for s in $list

do

      echo "hi,this is sytem script speaking.bye..." > /dev/$s

done

: AIX,还可以使用wall命令.

 40.输出到stderr

echo “this is error information”  > &2

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值