Perl-进程管理1

1. system函数

在perl中启动子程序最简单的方法是用system函数

system 'date';

这类命令来自操作系统,它们能提供什么以及如何实现都依赖操作系统,perl是请求操作系统调用它们

所运行的perl程序称为父进程,当它运行时,system命令根据当前进程创建一份拷贝,这份拷贝称为子进程。子进程会立即切换到要运行的外部命令上。比如这里的data,它继承了原来进程中perl的标准输入、标准输出以及标准错误,也就是说,由外部命令data输出的日期与时间字符串会立即传送到当前perl程序的STDOUT句柄所指向的地方

system 'ls -l $HOME';
system "ls -l $HOME";

这里的$HOME是shell的环境变量,保存当前用户的主目录,$HOME不是perl变量,所以不需要内插,放在双引号中的话反而不对

子进程正在运行时,perl会等待它结束。如果date命令耗时37秒,perl就会暂停37秒,不过,可以用shell提供的功能来启动后台进程

system "long_running_command with parameters &";

这句命令会启动shell,shell注意到命令行末尾有一个与号,于是shell让后台执行long_running_program,在进程执行完成后结束进程并立即退出。之后,perl发现shell执行完毕并返回,于是继续做别的事情。在这个例子中,long_running_command其实是perl的孙进程,perl无法直接控制或访问它

windows没有后台运行的机制,但start可以启动外部命令,并且无需父进程等待它执行完毕

system 'start /B long_running_command with parameters';
system 'for i in *; do echo == $i ==; cat $i; done';

2. 避免使用shell

my $tarile = 'something*wicked.tar';
my @dir = qw(fred|flintstone <barney&rubble> betty );
system 'tar', 'cvf', $tarfile, @dirs;

system可以使用一种交间接对象的写法,第一个参数后面不用逗号,例如system {'fred'} 'barney;',它实际上会运行程序barney,却骗自己程序名是’fred’

下面的是有安全隐患的写法

system "tar cvf $tarfile @dirs"; # 蛋糕了!!!

这段代码会把一大堆压缩后的数据通过管道传给flintstone命令,然后将它放在后台运行,同时把输出信息写入名为betty的文件
@dirs是不是列表并不重要,因为perl会简单地把它内插后变成单个参数传递给system

用system的多参形式启动子进程会失去shell提供的设定I/O重定向、后台进程等等功能

system的单参数调用形式基本上等效于下面这个system的多参数调用形式

system $command_line;
system 'bin/sh', '-c'. $command_line;

system操作符的返回值是根据子进程的结束状态来决定的

unless (system 'date'){
	# 返回值会是0,表示成功
	print "We gave you a date, OK!\n";
}

在unix里,退出值0代表正常,非0退出值则代表有问题。这是少数“虽然是0,布尔为假,但却表示成功,实为真”的情况,因为成功没啥好说的,一个零就能表示,错误有好多种,可以用不同的退出码代表

!system 'rm -rf files_to_delete' or die 'something went wrong';

在这个例子中,若要显示错误信息则不能引入$!变量,因为错误多半发生在rm命令的运行时刻,不是$!能捕捉的系统调用相关命令

system的返回值是一个高低各8位的字节。“高”8位是程序的退出码,可以通过位操作符将它降低8位后取得

my $return_value = system( ... );
my $child_exit_code = $return_value >> 8;

“低”8位包含了很多信息,其中最高的以为表示程序运行时是否发生了core dump事件。利用十六进制数和二进制数可以遮蔽掉不干兴趣的位

my $low_octet = $return_value & 0xFF; # 遮蔽过滤掉高8位
my $dumped_core = $low_octet & 0b1_0000000; # 或写成128
my $signal_number = $low_octet & 0b0111_1111; # 或写成0x7f或127
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值