进程启动函数包括system,exec,eval,fork:
- # eval启动一个新的进程,并执行perl语句。执行完所有语句后eval返回。如果有错误$@会为非空值。
- eval ("print \"new process\\n\"");
- eval { print "inside eval\n"; };
- eval { die "dead"; }; print $@."\n";
- # system 启动一个程序,并等待该程序结束。返回值为错误码。0表示没有错误。
- $ret = system("ls"); print $ret."\n";
- # fork 启动一个新进程,并立即返回,返回值为新进程的ID。两个进程同时运行。
- pipe (IN, OUT); # 建立一个管道,以便fork后的两个进程通信
- $id = fork();
- if ($id == 0) {
- # 子进程
- close IN;
- print OUT "From child process\n";
- close OUT;
- print "Before calling exec\n";
- exec ("ls -l"); # 与system类似,但调用该函数会中断当前进程。
- print "After calling exec\n"; # 这条语句不会被调用。
- } else {
- # 父进程
- close OUT;
- while (<IN>) { print "Parent process get message: $_\n" and break if $_; }
- close IN;
- }
进程终止函数有die,exit,kill:
- # 进程终止函数
- print "Input one of the following commands: die/warn/exit: ";
- while (<STDIN>)
- {
- if ($_ =~ /^die$/i) { die "Die as you wish\n"; } # die向STDERR输出并退出
- elsif ($_ =~ /^warn$/i) { warn "I'm warning you!\n"; last; } # warn向STDERR输出但不退出
- elsif ($_ =~ /^exit$/ip) { print "Exit with code 0.\n"; exit(0); } # exit退出,可以返回一个错误码
- elsif ($_) { print("Unknown command.\n"); last; }
- }
- $pid = fork();
- if ($pid == 0) {
- while (1) {
- print "Child process: I'm still here!\n"; sleep(5); # 等待5秒钟
- }
- } else {
- print "Input \"kill\" to kill the child process:\n";
- while (<STDIN>) {
- if ($_ =~ /kill/) {
- print "killing child process\n";
- kill (9, $pid); # kill(signal, proclist) 9为杀死进程的信号
- last;
- }
- }
- wait(); # 等待子进程结束
- print "child process is killed!\n";
- }
除了上面代码中的
sleep和
wait可以中断当前进程,另一个函数
waitpid (procid, waitflag)可以等待特定的子进程.
函数caller可以得到函数调用者的信息:
- sub knowcaller {
- ($package, $file, $line) = caller();
- print "$package - $file - $line\n";
- }
times可以得到进程运行时间的信息:
- $pid = fork();
- for ($i = 1; $i < 10000; $i++) { print $i; } # 增加运行时间
- if ($pid == 0) { for ($i = 1; $i < 10000; $i++) { print $i; } } # 增加子进程的运行时间
- else { wait(); }
- # times 返回四个浮点数的列表:
- # 1、程序耗用的用户时间
- # 2、程序耗用的系统时间
- # 3、子进程耗用的用户时间
- # 4、子进程耗用的系统时间
- ($processUserTime, $processSystemTime, $childProcessUserTime, $childProcessSystemTime) = times();
- print $pid ? "Parent process: " : "Child process: ";
- print "$processUserTime, $processSystemTime, $childProcessUserTime, $childProcessSystemTime\n";
- # Parent process: 0.05, 0.01, 0.08, 0
- # Child process: 0.08, 0, 0, 0
chroot (dir)可以改变程序的根目录.
下面是一些数学函数:
- $PI = 3.1415926;
- print "sin30=".sin($PI/6)."\n"; # 0.5
- print "cos60=".cos($PI/3)."\n"; # 0.5
- print "atan2(1)=".atan2(4, 4)."\n"; # PI/4即45度
- print "sqrt(4)=".sqrt(4)."\n"; # 平方根
- print "log(9)=".log(9)."\n"; # 以e为底的自然对数
- print "abs(-11)=".abs(-11)."\n"; # 绝对值
- srand(0); # 初始化随机数生成器
- for ($i = 0; $i < 10; $i++) {
- print rand(100)." "; # 100以内的随机(浮点)数
字符串的处理函数:
- # 查找子串
- $pos = index ("Here is China", "is");
- print $pos."\n"; # 5
- $pos = index ("Case sensitive", "case");
- print $pos."\n"; # -1 大小写敏感
- $pos = index ("Regular Expression", ".*gular");
- print $pos."\n"; # -1 不支持正则表达式
- $pos = index (".*special .*words", ".*", 3);
- print $pos."\n"; # 10 从第三个字符开始寻找
- # 右端开始查找子串
- $pos = rindex ("an c an", "an");
- print $pos."\n"; # 5 从最右开始查找
- $pos = rindex ("an c an", "an", 3);
- print $pos."\n"; # 0
- # 字符串的长度
- $len = length ("a word");
- print $len."\n"; # 6
- # pos 返回最后一次模式匹配的位置
- $string = "an ce an";
- print pos($string)."\n"; # null 未匹配前,开始匹配的位置在0
- $string =~ /an/g;
- # substr(expr, skipchars, length) 跳过skipchars个字符后从字符串expr中抽取长度为length的子
- 字符串
- $substring = substr("abcdefghi", 3, 3);
- print $substring."\n"; # "def"
- print substr("abcdefghi", 4)."\n"; # "efghi"
- $string = "abcdefghi";
- substr($string, 4) = "xyz"; # 将$string中的子串替换掉
- print $string."\n"; # "abcdxyz"
- # study 用一种内部格式提高变量的访问速度,同一时刻只对一个变量起作用
- $var = 9;
- study ($var);
- $var += 100;
- print $var."\n"; # 109
- # lc 将字符串变为小写
- print lc ("AbCDefg")."\n"; # abcdefg
- # uc 将字符串变为大写
- print uc ("AbCDefg")."\n"; # ABCDEFG
- # lcfirst 将首字符变为小写
- print lcfirst ("ABCDEFG")."\n"; # aBCDEFG
- # ucfirst 将首字符变为大写
- print ucfirst ("abcdefg")."\n"; # Abcdefg
- # quotemeta 在非单词的字母前面加上反斜线
- $string = 'a!b@c#d$1%2^3&'; # 等效于$string =~ s/(\W)/\\$1/g;
- print quotemeta($string)."\n"; # a\!b\@c\#d\$1\%2\^3\&
- # join 把数组连接为字符串
- print join("-", 1, 2, 3, 4)."\n"; # 1-2-3-4
- # sprintf 生成格式化的字符串
- printf ("%2.3f, %3d\n", 3.2, 87); # 3.200, 87
标量转换函数:
- # chop 删除字符串的最后一个字符或数组的所有元素的最后一个字符
- $string = "abcd";
- print chop($string)."\n"; # d; 返回被删的字符
- print $string."\n"; # abc
- @array = ("az", "by", "cx", "dw", "ev");
- print chop(@array)."\n"; # v; 最后一个元素中被删的字符
- print "@array\n"; # a b c d e
- # chomp 删除最后一个由$/定义的换行字符
- $string = "ab\n";
- print chomp($string)."\n"; # 1 删除了一个换行符
- $string = "ab\n\n";
- print chomp($string)."\n"; # 1
- $string = "ab";
- print chomp($string)."\n"; # 0
- @array = ("a\n", "b\n", "c", "d", "e\n");
- print chomp(@array)."\n"; # 3 共删除了三个换行符
- # crypt(salt) 用DES算法加密字符串,salt是两个字符的字符串,定义如何改变DES算法
- $result = crypt ("abcd", "xy");
- print $result."\n"; # xySwiJOgXKttU
- # hex 将十六进制字符串转化为十进制数
- $num = hex("1f");
- print $num."\n"; # 31
- # int 将浮点数舍去小数部分转化为整型数
- $num = int(21.34);
- print $num."\n"; # 21
- # oct 将八进制或十六进制字符串转化为十进制数
- $num = oct("27");
- print $num."\n"; # 23
- $num = oct("0x1f");
- print $num."\n"; # 31
- # ord 返回单个字符的ASCII值
- print ord("A")."\n"; # 65
- # chr 返回ASCII值的相应字符
- print chr(65)."\n"; # A
- # defined 判断一个变量、数组或数组的一个元素是否已经被赋值。
- $var = 8;
- if (defined($var)) { print "defined\n"; }
- $var = ""; # 仍然视为被定义
- print (defined($var) ? "defeind" : "undefined")."\n";
- # undef 取消变量、数组或数组元素甚至子程序的定义,回收其空间。返回值始终为未定义值,此值与空串等效
- $a = 5;
- undef($a);
- print $a."\n";
- print (defined($a) ? "defeind" : "undefined")."\n";
数组相关函数:
- # grep从数组中找到与模式匹配的元素
- @array = (ab, d3, fa, d5);
- @foundlist = grep(/d\d/, @array);
- print "@foundlist\n"; # d3 35
- # splice(@array, skipelements, length, @newlist) 可以拼接两个数组. skipelements是略过的元素数,length是替换掉的元素数.
- @array = (1, 2, 3, 4);
- @other = (a, b, c);
- splice (@array, 2, 1, @other); # 把第三个元素替换成新列表
- print "@array\n"; # 1 2 a b c 4
- splice (@array, 2, 3); # 从第三个元素起删除三个元素
- print "@array\n"; # 1 2 4
- @other = (o, p, "q");
- splice (@array, -1, 0, @other); # 在数组倒数第一个元素前添加新元素
- print "@array\n"; # 1 2 o p q 4
- # shift从数组首部弹出一个元素
- @array = (1, 2, 3, 4);
- print shift(@array)."\n"; # 1 返回弹出的元素
- print "@array\n"; # 2 3 4
- # unshift在数组首部压入一个元素
- @array = (1, 2, 3, 4);
- print unshift(@array, 0)."\n"; # 5 返回压入元素后数组的大小
- print "@array\n"; # 0 1 2 3 4
- # push在数组末尾添加元素
- @array = (1, 2, 3, 4);
- print push(@array, -1, -2)."\n"; # 6 返回新的数组大小
- print "@array\n"; # 1 2 3 4 -1 -2
- # pop弹出末尾的元素
- @array = (1, 2, 3, 4);
- print pop(@array)."\n"; # 4 返回弹出的元素
- print "@array\n"; # 1 2 3
- # split 把字符串分割成一个数组
- @array = split(/\W/, "a*b^c-d", 3); # 最后一个元素表示最后分割成三个元素
- print "@array\n"; # a b c-d
- # sort 按字母序给数组排序
- @sorted = sort("eye", "ear", "mouth", "face");
- print "@sorted\n"; # ear eye face mouth
- # reverse 将数组倒转
- @array = (eye, ear, mouth, face);
- @reversed = reverse(@array);
- print "@reversed\n"; # face mouth ear eye
- # map 可以把数组中的各个元素代入到一个表达式中进行运算
- @list = (1, 2, 3);
- @results = map ($_*2, @list); # $_是元素要代入的位置
- print "@results\n"; # 2 4 6
- # wantarray 可以知道调用者用标量还是数组存储函数的返回值, 比如一些内置函数如<STDIN>.
- sub foo {
- package FOO;
- unless (@array or $initialized) {
- @array = (1, 2, 3, 4);
- $initialized = 1;
- }
- if (wantarray()) {
- return @array;
- } else {
- return shift(@array) if @array > 0;
- $initialized = "";
- return "";
- }
- }
- @results = foo(); # 返回值传入数组中
- print "@results\n"; # 1 2 3 4
- while ($ret = foo()) { # 返回值传入普通变量中
- print "$ret\n"; # 1 2 3 4
- }
哈希表相关函数:
- %hash = ("a"=>1, "b"=>2, "c"=>3);
- # keys 返回所有关键字列表
- @keys = keys(%hash);
- print "@keys\n"; # c b a
- # values 返回值列表
- @values = values(%hash);
- print "@values\n"; # 3 1 2
- # each 返回下一个键值对,用来遍历
- while (($key, $value) = each(%hash)) {
- print "$key-$value\n";
- }
- # delete 删除一个元素
- $value = delete ($hash{"b"});
- print $value."\n"; # 2
- $value = delete ($hash{"d"}); # 删除一个不存在的元素
- print $value."\n"; # null
- # exists 判断某元素是否存在
- print exists($hash{"c"})."\n"; # 1
- print exists($hash{"d"})."\n"; # null
最后贴两段关于
Perl和C语言交互的函数:
函数名
|
pack
|
调用语法
|
formatstr = pack(packformat, list);
|
解说
|
把一个列表或数组以在实际机器存贮格式或C等编程语言使用的格式转化(包装)到一个简单变量中。参数packformat包含一个或多个格式字符,列表中每个元素对应一个,各格式字符间可用空格或tab隔开,因为pack忽略空格。
除了格式a、A和@外,重复使用一种格式多次可在其后加个整数,如:
$twoints = pack ("i2", 103, 241);
把同一格式应用于所有的元素则加个*号,如:
$manyints = pack ("i*", 14, 26, 11, 83);
对于a和A而言,其后的整数表示要创建的字符串长度,重复方法如下:
$strings = pack ("a6" x 2, "test1", "test2");
格式@的情况比较特殊,其后必须加个整数,该数表示字符串必须的长度,如果长度不够,则用空字符(null)补足,如:
$output = pack ("a @6 a", "test", "test2");
pack函数最常见的用途是创建可与C程序交互的数据,例如C语言中字符串均以空字符(null)结尾,创建这样的数据可以这样做:
$Cstring = pack ("ax", $mystring);
下表是一些格式字符与C中数据类型的等价关系:
字符
|
等价C数据类型
|
C
|
char
|
d
|
double
|
f
|
float
|
i
|
int
|
I
|
unsigned int (or unsigned)
|
l
|
long
|
L
|
unsigned long
|
s
|
short
|
S
|
unsigned short
|
完整的格式字符见下表。
|
格式字符
|
描述
|
a
|
用空字符(null)补足的字符串
|
A
|
用空格补足的字符串
|
b
|
位串,低位在前
|
B
|
位串,高位在前
|
c
|
带符号字符(通常-128~127)
|
C
|
无符号字符(通常8位)
|
d
|
双精度浮点数
|
f
|
单精度浮点数
|
h
|
十六进制数串,低位在前
|
H
|
十六进制数串,高位在前
|
i
|
带符号整数
|
I
|
无符号整数
|
l
|
带符号长整数
|
L
|
无符号长整数
|
n
|
网络序短整数
|
N
|
网络序长整数
|
p
|
字符串指针
|
s
|
带符号短整数
|
S
|
无符号短整数
|
u
|
转化成uuencode格式
|
v
|
VAX序短整数
|
V
|
VAX序长整数
|
x
|
一个空字节
|
X
|
回退一个字节
|
@
|
以空字节(null)填充
|
函数名
|
unpack
|
调用语法
|
@list = unpack (packformat, formatstr);
|
解说
|
unpack与pack功能相反,将以机器格式存贮的值转化成Perl中值的列表。其格式字符与pack基本相同(即上表),不同的有:A格式将机器格式
字符串转化为Perl字符串并去掉尾部所有空格或空字符;x为跳过一个字节;@为跳过一些字节到指定的位置,如@4为跳过4个字节。下面看一个@和X合同
的例子: $longrightint = unpack ("@* X4 L", $packstring);
此语句将最后四个字节看作无符号长整数进行转化。下面看一个对uuencode文件解码的例子:
1 : #!/usr/local/bin/perl
2 :
3 : open (CODEDFILE, "/u/janedoe/codefile") ||
4 : die ("Can't open input file");
5 : open (OUTFILE, ">outfile") ||
6 : die ("Can't open output file");
7 : while ($line = ) {
8 : $decoded = unpack("u", $line);
9 : print OUTFILE ($decoded);
10: }
11: close (OUTFILE);
12: close (CODEDFILE);
当将pack和unpack用于uuencode时,要记住,虽然它们与UNIX中的uuencode、uudecode工具算法相同,但并不提供首
行和末行,如果想用uudecode对由pack的输出创建的文件进行解码,必须也把首行和末行输出(详见UNIX中uuencode帮助)。
|
函数名
|
vec
|
调用语法
|
retval = vec (vector, index, bits);
|
解说
|
顾名思义,vec即矢量(vector)函数,它把简单变量vector的值看作多块(维)数据,每块含一定数目的位,合起来即一个矢量数据。每次的调用
访问其中一块数据,可以读取,也可以写入。参数index就象数组下标一样,提出访问哪一块,0为第一块,依次类推,要注意的是访问次序是从右到左的,即
第一块在最右边。参数bits指定每块中的位数,可以为1,2,4,8,16或32。
|
例子
|
1 : #!/usr/local/bin/perl
2 :
3 : $vector = pack ("B*", "11010011");
4 : $val1 = vec ($vector, 0, 4);
5 : $val2 = vec ($vector, 1, 4);
6 : print ("high-to-low order values: $val1 and $val2\n");
7 : $vector = pack ("b*", "11010011");
8 : $val1 = vec ($vector, 0, 4);
9 : $val2 = vec ($vector, 1, 4);
10: print ("low-to-high order values: $val1 and $val2\n");
|
结果
|
high-to-low order values: 3 and 13
low-to-high order values: 11 and 12
|
阅读(1197) | 评论(0) | 转发(1) |