SHELL 脚本编程(2)

2.7 SHELL函数

可以将SHELL中需要重复执行的代码写成函数,与C变成的函数一致。

1 函数格式

定义函数的格式为:

函数名()

{

...

}

或者

函数名(){

...

}

两者方式都可行。如果愿意,可在函数名前加上关键字function,建议增加。

function 函数名()

{

...

}

2 向函数传入参数

函数可以带参数调用,调用方式为

函数名称 参数列表

函数取得传入的参数,与SHELL得到调用的参数完全一致:

判断参数个数:

$#

取参数:

$1 $2 …

3 函数返回参数

函数可以使用return 返回调用参一个值。调用者可以在调用函数后得到函数的返回值:

$?得到,如:

#调用格式:aaa parameter

aaa()

{

return 1

}

#错误用法

a=`aaa para` #无法得到返回值1

#正确用法

aaa para

ret=$?

如果使用exit,将退出SHELL程序

4 将常用函数写成库函数

为了重复利用代码,可以将函数写成库函数的方式,然后在SHELL中包含进行即可使用:

. libraryfile

2.8 其他基本语法

1 条件连接符

and与

命令行:command1 && command2 #如果command1执行成功,执行commnad2

如:rm * && echo "File successfully removed"

(建议不要使用以上语法,因为语法不常用,可读性不强)

表达式:express1 && express2

如:if [ $1 -eq 1 ] && [ $1 -eq 1 ]

then

...

fi

or或

命令行:command1 || command2 #仅当前一个命令执行出错时才执行后一条命令

如:rm * || echo "File successfully removed"

(建议不要使用以上语法,因为语法不常用,可读性不强)

表达式:express1 || express2

如:if [ $1 -eq 1 ] || [ $1 -eq 1 ]

then

...

fi

2 包含库函数

#. 空格之后将文件的路径, 一般放在程序的起始部分

. ./comm_func.sh.rc

3 信号处理

trap "echo ___ $0 interrupted ___; exit 1" 2

4 分割符

SHELL默认的分割符IFS为空格与TAB键。程序中可以使用定制的分割符

如:从dbaccess下载数据没有指定delimiter时,字段分割为”|”

OLD_IFS=$IFS

IFS=”|”

Read col1 col2 col3 < datafile

IFS=$OLD_IFS

【3】常用命令与操作

3.1 文件

1)文件类型,ls –al 中第一列的第一个字符:

drwxr-xr-x 12 smp20 sms 1024 Aug 13 15:36 .dt

d 目录。

l 符号链接(指向另一个文件)。

s 套接字文件。

b 块设备文件。比如informix操作的存储文件为块设备

c 字符设备文件。比如/dev/null空设备

p 命名管道文件。即进程通信使用的PIPE文件

- 普通文件,或者更准确地说,不属于以上几种类型的文件

2)文件权限,ls –al 中第一列的第2-10个字符

(2-4字符) 文件属主的权限

(5-7字符) 同组用户的权限

(8-10字符) 其他用户的权限

3)改变权限位

chmod命令的一般格式为:

chmod [who] operator [permission] filename

who的含义是:

u 文件属主权限。

g 同组用户权限。

o 其他用户权限。

a 所有用户(文件属主、同组用户及其他用户)。

operator的含义:

+ 增加权限。

- 取消权限。

= 设定权限。

permission的含义:

r 读权限。

w 写权限。

x 执行权限。

s 文件属主和组set-ID。

t 粘性位*。

l 给文件加锁,使其他用户无法访问。

或者:

chmod 权限值 filename

文件属主 同组用户 其他用户

rwx rwx rwx

4+2+1 4+2+1 4+2+1

4)目录权限位

目录的读权限位意味着可以列出其中的内容。写权限位意味着可以在该目录中创建文件,如果不希望其他用户在你的目录中创建文件,可以取消相应的写权限位。执行权限位则意味着搜索和访问该目录

5)改变文件的属主

chown命令的一般形式为:

chown -R -h owner file

- R选项意味着对所有子目录下的文件也都进行同样的操作。- h选项意味着在改变符号链接文件的属主时不影响该链接所指向的目标文件。一旦将文件的所有权交给另外一个用户,就无法再重新收回它的所有权

6) umask

umask命令确定了你创建文件的缺省模式。这一命令实际上和chmod命令正好相反

umask命令是在/etc/profile文件中设置的,每个用户在登录时都会引用这个文件,所以如果希望改变所有用户的umask,可以在该文件中加入相应的条目。如果希望永久性地设置自己的umask值,那么就把它放在自己$HOME目录下的. profile或.bash_profile文件中。

对于SMP或者SCP,我们定义在.cshrc中,这样登陆即生效。如:umask 002,这样创建的文件的权限为777-002=775

7) 判断文件某些特性

-r file #是否存在并且可读

-w file #是否存在并且可写

-s file #是否存在并且文件大小大于0

-f file #是否存在并且是规则文件

-d file #是否存在并且为目录

-x file #是否存在并且可以执行

-p file #是否存在并且为管道文件

3.2 数值操作

可以使用:expr或者bc命令,KSH可以使用let

使用 expr 应用程序

1) expr

n1=3

n2=5

n=`expr $n1 + $n2 `

注意:+等操作符2侧需要使用空格格开

如:

>expr 10000 + 1111 #相加

>expr 10000 \* 1111 #相乘

ksh 中可使用 let

n1=3

n2=5

let n=n1+n2

2) bc

使用bc可以计算任意长度的计算,不会溢出

>echo "1000000000000000000000000000000*1111" | bc

111100000000000000000000000000000

3.3 合并与分割

常用的合并与分割命令有:

• sort

• cut

• split

1) sort排序

sort -cmur -o 输出文件 –t 分割符 +n 输入文件

下面简要介绍一下s o r t的参数:

-c 测试文件是否已经分类。

-m 合并两个分类文件。

-u 删除所有复制行。

-r 逆向排序DESC,默认为正向ASC

如:将basetab_pps文件按第4个字段逆向排序

sort –t\| -r +3 basetab_pps.unl > basetab_pps.unl.sort

注意:不能使用-t|,因为|在SHELL中属于管道符号,需要使用\|

2) cut切割

cut用来从标准输入或文本文件中剪切列或域。剪切文本可以将之粘贴到一个文本文件。

下一节将介绍粘贴用法。

cut一般格式为:

cut [options] file1 file2

下面介绍其可用选项:

-c list 指定剪切字符数。

-f field 指定剪切域数。

-d 指定与空格和tab键不同的域分隔符。

-c用来指定剪切范围,如下所示:

-c1,5-7 剪切第1个字符,然后是第5到第7个字符。

-c1-50 剪切前50个字符。

-f 格式与-c相同。

-f1,5 剪切第1域,第5域。

-f1,10-12 剪切第1域,第1 0域到第1 2域。

如:从字符串中”aaabb:aaaaa:bbb”将”aaaaa”切割出来

>echo ”aaabb:aaaaa:bbb” | cut –d “:” –f2

3) split

split用来将大文件分割成小文件。有时文件越来越大,传送这些文件时,首先将其分割可能更容易。使用vi或其他工具诸如sort时,如果文件对于工作缓冲区太大,也会存在一些问题。因此有时没有选择余地,必须将文件分割成小的碎片。

split命令一般格式:

split –output-file-line input-filename output-filename

这里output-file-size指的是文本文件被分割的行数。split查看文件时,output-file-line选项

指定将文件按每个最多1000行分割。如果有个文件有2800行,那么将分割成3个文件,分别有1000、1000、800行。每个文件格式为x[aa]到x[zz],x为文件名首字母, [aa]、[zz]为文件名剩余部分顺序字符组合,

3.4 匹配或者过滤操作

1 grep的使用

grep可以从输入的字符中,过滤某些或者过滤掉某个特定字符的命令。

一般使用为:

grep “特征字符串” inputFile

grep –v “特征字符串” inputFile

2 awk命令的使用

awk是可以使用很复杂,但是能完成某些特定功能,并且常使用的一个命令。使用用法:

awk [–F 分隔符] ‘模式’ inputfile

-F可以指定域或者列之间的分割符,如果不指定,使用默认的分割符(空格或者TAB)。比如对于分割unload命令下载的文件, 可以指定 –F |

对于模式中的使用分割符分割后的域,标记$1,$2 . . . $n,$0标识所有的域。

为打印一个域或所有域,使用p r i n t命令

比如打印当前目录的所有文件的大小名称:

>ls –al | awk ‘{ print $5, $9}’ #大小与文件名称使用空格格开,即$5,$9使用空格连接

>ls –al | awk ‘{ print $5”|”$9}’ #大小与文件名称使用|格开,即$5,$9使用|连接

使用BEGIN模式打印头部信息:

>ls –al | awk ‘BEGIN {print “size filename”} { print $5”\t”$9}’ #相当于打印列的标题

使用END模式打印尾部信息:

>ls –al | awk ‘{print $5”\t”$9} END{print “finished”}’ #在列出文件后,加上finished字符

awk中使用正则表达式

awk中正则表达式匹配操作用到的字符有:

\ ^ $ . [] | () * + ?

用法:

awk [-F 分割符] ‘{if (express) 操作}’

即指定域满足express表达式的行,才打印出来.

如打印目录文件中包含sms的文件:

>ls –al | awk ‘{if ( $9~/sms/) print $0}’

如打印目录文件大小大于100000字节的文件:

>ls –al | awk ‘{if ( $5>100000) print $0}’

awk中还有很多用法,在此不列出来

3 sed命令

3.5 信号处理

信号就是系统向脚本或命令发出的消息,告知它们某个事件的发生。这些事件通常是内存错误,访问权限问题或某个用户试图停止你的进程。信号实际上是一些数字。下表列出了最常用的信号及它们的含义列出所有信号:

>kill –l

HUP INT QUIT ILL TRAP IOT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM USR1

USR2 CLD PWR VTALRM PROF IO WINCH STOP TSTP CONT TTIN TTOU

一些信号的含义:

1 SIGHUP 挂起或父进程被杀死

2 SIGINT 来自键盘的中断信号,通常是< C T R L - C >

3 SIGQUIT 从键盘退出

9 SIGKILL 无条件终止

11 SIGSEGV 段(内存)冲突

15 SIGTERM 软件终止(缺省杀进程信号)

1 发出信号:

kill –信号 进程号

注明:kill –9 进程号 杀死进程时,操作系统直接将进程从内核清除,不作退出的处理

2 检测信号或者捕捉信号

有些信号可以被应用程序或脚本捕获,并依据该信号采取相应的行动。另外一些信号不

能被捕获。例如,如果一个命令收到了信号9,就无法再捕捉其他信号。

当脚本捕捉到一个信号后,它可能会采

取下面三种操作之一:

1) 不采取任何行动,由系统来进行处理。

2) 捕获该信号,但忽略它。

3) 捕获该信号,并采取相应的行动

如果需要捕捉信号后,采用自定义的操作,可以使用trap命令:

trap name signal(s)

其中,name是捕捉到信号以后所采取的一系列操作。实际生活中, name一般是一个专门用来处理所捕捉信号的函数。Name需要用双引号(“ ”)引起来。Signal就是待捕捉的信号。

下表列出了一些最常见的trap命令用法:

trap "" 2 3 忽略信号2和信号3,用户不能终止该脚本

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

trap 2 3 复位信号2和3,用户可以终止该脚本

如:收到3( SIGQUIT 从键盘退出),打印一行“proc received SIGQUIT and exit”

#!/bin/ksh

trap “fun_exit” 3

fun_exit()

{

echo “proc received SIGQUIT and exit”

exit 1

}

echo “start running”

exit 0

3.6 设置终端参数

stty可以用来设置与限制终端属性,如:终端与计算机之间的传输率、退格、中断等。

echo[-echo] 是否回显

intr 生成中断信号,默认使用del按键生成

erase 退格键,即擦除前面一个字符

【4】其他

3.1 使用不同的壳执行命令文件

1. 如果Script的第一个非空白字元不是"#",则它会使用Bourne Shell。

2. 如果Script的第一个非空白字元是"#"时,但不以"#!"开头时,则它会使用C Shell。

3. 如果Script以"#!"开头,则"#!"後面所写的就是所使用的Shell,而且要将整个路径名称指出来,这里建议使用第三种方式指定Shell ,以确保所执行的就是所要的。Bourne Shell的路径名称为/bin/sh ,而C Shell 则为/bin/csh。 我们一般使用ksh, 路径为/bin/ksh

3.2 使用不同SHELL的区别

BSH:

设置环境变量使用export var=var_value; var=var_valu; export var

CSH/KSH:

设置环境变量使用setenv var var_value

一些KSH独有的特征:

1)KSH环境变量

HISTSIZE:历史命令数量,默认为128,可以在.chsrc中将其设置为其他值

TMOUT :超时自动退出,用于一段时间没有键入命令,强制退出

2) 别名

可以定义自己的标识,标识定义的命令。比如:

alias dba dbaccess $TELLIN_DBNAME

3) 支持数组变量

3.3 SHELL程序的返回值不能超出255,否则返回值将不确定

3.4 read命令将输入的多余的part给最后一个变量

>read var1 var2

aa bb cc

>echo $var1

aa

>echo $var2

bb cc

3.5 调试

使用-x

1 在SHELL程序指定执行为调试模式

#!/bin/sh –x

2在命令行中指定调试模式执行

指定SHELL –x 程序名称,如:

sh –x update_iuser214.sh

3.6 执行SHELL

前台执行:

>sh 程序名称

>程序名称

后台执行:

>sh 程序名称 &

>程序名称 &

3.7 移植性

目前智能业务部的设备选型中,小型机从IBM/HP/SUN 3家中选择。相应我们的SHELL一般需要在AIX,HP-UX,SunOS上应当保持一致。即SHELL程序一般需要在3中操作系统上进行移植。

可以使用uname –s确定机器的操作系统,比如:

#机器类型

OsType=`uname -s`

if [ "-$OsType" = "-SunOS" ]; then

elif [ "-$OsType" = "-HP-UX" ]; then

elif [ "-$OsType" = "-AIX" ]; then

else

echo "ERROR: system not support this machine type $OsType"

eixt 1

fi

大部分常见的UNIX命令在以上3中操作是一致的,但是某些命令则具有差异(如ftp的ls在HP-UX为nlist)。如果碰到与操作系统相关的地方,则需要根据操作系统作相应处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值