系统管理
- 进程管理
- system()
system 'date';
防止perl变量内插可以
1) 使用单引号
system 'ls -l $HOME';
2) 使用转义字符
system "ls -l \$HOME";
perl程序为父进程。启动的进程的标准输入/输出,错误输出会定向到perl相关句柄指向的地方。同时,启动的进程会继承perl父进程的环境变量(可以在perl程序中修改%ENV,比如$ENV{‘PATH’})。system函数的参数就是shell命令。system运行时会阻塞perl父进程。
当然也可以在后台运行shell命令:
system "long_running_command with parameters &";
扩展shell的通配符
system 'for i in *; do echo === $i ===; cat $i; done';
system 'for i in *.log; do echo === $i ===; cat $i; done';
使用system的多参数调用
system 'tar', 'czvf', $file, @dirs;
system的返回值由子进程的结束状态决定。
- 修改环境变量
$ENV{'PATH'}="/home/user/bin:$ENV{'PATH'}";
delete $ENV{'IFS'};
my $make_result=system 'make';
注意:
修改从父进程继承来的环境变量并不能影响shell或其他父进程。
- exec()
exec会让perl自己去执行任务。
chdir '~/bin' or die "Can't chdir to ~/bin: $!";
exec 'test5.pl', '-s', '~/ip.txt', @ARGV;
- 反引号
用于捕获输出字符串。
chomp(my $now=`date`); #shell会自动去除``执行结果结尾的回车换行,但perl不会。
print "The time is now $now";
“ `` ” vs. “ qx ”
my @functions=qw( int rand sleep length hex eof exit sqrt umask);
my %meaning=;
foreach (@functions){
$about{$_}=`perldoc -t -f $_`;
}
或者(效果一样,但后者便于避免转义)
foreach (@functions){
$about{$_}=qx(perldoc -t -f $_);
}
防止perl变量内插
my $output=qx'echo $$'; # $$是shell中的PID
一般反引号只用于捕获命令回显的场合。对于多行回显可以:
在标量上下文中
my $who=`who`;
my @whos=split /\n/, $who;
在列表上下文中
my @whos=`who`;
或者
foreach (`who`){
my($user, $tty, $date)=/(\S+)\s+(\S+)\s+(.*)/;
$ttys{$user}.="$tty at $date\n"; #利用哈希的键值来去重
}
标量会将命令返回的多行文本连带\n(\N表示换行符之外的字符)一起存储,而使用列表则会对每行文本逐一存储。
- 错误管理
- eval块
eval{
...
}; #eval是个表达式,所以末尾有个分号。
只要eval发现他的检测范围内出现致命错误,就会立即停止运行整个块,退出后继续运行剩下的内容。eval的返回值就是最后一条表达式的执行结果。
my $barney=eval{ $a/$b } // 'NaN';
print "balabala... \$b: $@" if $@;
如果捕获到错误,eval会返回undef,并在变量$@中设置错误信息。
eval块是可以嵌套的。
在perl中使用die抛出异常,在eval中捕获,当然也可以使用Try::Tiny模块。
也可以使用autodie编译指令。
use autodie;