Perl笔记6

来源:互联网 发布:小米4为何没有4g网络 编辑:程序博客网 时间:2024/05/01 10:38

第十六章 进程管理
(1) system函数
在Perl中,启动子进程最简单的方法就是system函数
system 'date';
system 'ls -l $HOME';
system "ls -l \$HOME";


后台进程:
system "long_running_command with parameters &";


system 'for i in *; do echo == $i ==; cat $i; done';


(2) 避免使用shell
system操作符的返回值是根据子进程结束状态来决定的。在Unix里,退出值0代表正常,非零退出值则代表有问题。
use 5.0100;
my $return_code = system 'date';
say $return_code;
unless (system 'date')
{
    say "We gave you a date, OK!";
}


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


(3) 环境变量
在Perl中,环境变量可以通过%ENV哈希取得,其中每个键都代表一个环境变量
$ENV{'PATH'} = "/home/jiang/bin:$ENV{'PATH'}";
delete $ENV{'IF'};
my $make_result = system 'make';


(4) exec函数
system函数的所有语法也都适用于exec函数。
system函数会创建子进程,子进程在Perl睡眠期间执行任务,而exec函数却导致Perl进程自己去执行任务。
chdir '/tmp' or die "Cannot chdir /tmp: $!";
exec 'bedrock', '-o', 'args1', @ARGV;
一旦要执行的命令启动后,Perl便放手退出,无法再控制它,因此在exec调用之后写的任何代码都无法运行,不过如果启动过程出现错误,
那么后续语句还是可以继续运行的。


(5) 用反引号捕获输出结果
my $now = `date`; #里面包含了换行符
print "The time is now $now";


测试:
use 5.010;
my @functions = qw{ int rand sleep length hex eof exit sqrt umask };
my %about;


foreach (@functions)
{
    $about{$_} = `perldoc -t -f $_`;
}


foreach (keys %about)
{
    say "$_: $about{$_}";
}


除了反引号,你还可以使用更为一般化的引起操作符qx():
foreach (@functions)
{
    $about{$_} = qx(perldoc -t -f $_);
}


如果选用单引号作为分隔符的话,可以禁止变量内插。
选用shell进程编号变量$$而不是Perl的时候:
my $output = qx'echo $$';


将标准错误合并到标准输出:
my $output_with_errors =  `frobnitz -enable 2>&1`;


my $result = `some_questionable_command arg arg argh < /dev/null`;
这样子shell就会将输入重定向到/dev/null,接着再执行那个交互式命令,这样就算它要求输入,也只会读到文件结束符。


(6) 在列表上下文中使用反引号
my $who_text = `who`;
my @who_lines = split /\n/, $who_text;


测试:
foreach (`who`)
{
    my ($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/;
    $ttys{$user} .= "$tty at $date\n";    
}


(7) 用IPC::System::Simple执行外部进程
IPC::System::Simple模块非Perl自带模块。
use IPC::System::Simple qw(system);


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


它还提供了一个systemx函数,在执行外部命令时不会通过shell调用,所以不会碰到shell导致的意外情况:
systemx 'tar', 'cvf', $tarfile,@dirs;


如果要捕获外部命令的输出,只需把system或systemx改成capture或capturex就可以了,它的作用就好像是反引号一样。
my @output = capturex 'tar','cvf',$tarfile,@dirs;






原创粉丝点击