perl中的反勾号(``),system和exec
在perl中反勾号(``),system和exec都用来执行命令,这篇文章将给我们介绍它们各自的使用方法,联系,以及区别。 一、使用方法 1. 反勾号(``) 首先,我们有命令输入操作符,也叫反勾号操作符,因为它看起来象这样: 一个用反勾号(技术上叫重音号)引起的字串首先进行变量替换,就象一个双引号引起的字串一样。得到的结果然后被系统当作一个命令行,而且那个命令的输出成为伪文本的值。(这是一个类似 Unix shell 的模块。)在标量环境里,返回一个包含所有输出的字串。在列表环境里,返回一列值,每行输出一个值。(你可以通过设置 $/ 来使用不同的行结束符。) Demo3.pls #!/usr/bin/perl -w use strict; unless(open(FILE_H,"<F:\\log3.log")){ my @str = <FILE_H>; my $count = @str; for(my $i = 0;$i<$count;$i++){ Demo.pls #!/usr/bin/perl –w my @str = qx/perl F:\\Demo3.pls/;#或者` perl F:\\Demo3.pls `效果#一样 print "@str"; Log3.log 首先,我们有命令输入操作符,也叫反勾号操作符,因为它看起来象这样: $info = `finger $user`; 一个用反勾号(技术上叫重音号)引起的字串首先进行变量替换,就象一个双引号引起的字串一样。得到的结果然后被系统当作一个命令行,而且那个命令的输出成为伪文本的值。(这是一个类似 Unix shell 的模块。)在标量环境里,返回一个包含所有输出的字串。在列表环境里,返回一列值,每行输出一个值。(你可以通过设置 $/ 来使用不同的行结束符。) 代码解释,当执行Demo.pls时,my @str = qx/perl F:\\Demo3.pls/;这一句会被操作系统调用并且启动Demo3.pls,然后Demo3.pls会读取log3.log中的数据。 我们主要关注的是my @str = qx/perl F:\\Demo3.pls/;这句中的返回值@str,我们都知道@str是一个列表环境,反勾号返回Demo3.pls中的print的打印值,当然我们也可以使用标量环境,例如,my $str = qx/perl F:\\Demo3.pls/;这样也可以一次性的取出所有的数据。 最后总结:反勾号返回的是命令行返回的print的数值。具体的解释看上面的说明。 2. System l system PATHNAME LIST l system LIST 这个函数为你执行任何系统里的程序并返回该程序的退出状态——而不是它的输出。要捕获命令行上的输出,你应该用反勾号或者 qx//。system 函数的运转非常类似 exec,只不过 system 先做一个 fork,然后在 exec 之后等待执行的程序的结束。也就是说它为你运行这个程序并且在它完成之后返回,而 exec 用新的程序代替你运行的程序,所以如果替换成功的话它从不返回。 system(@args) == 0 or die "system @args failed: $?" 返回值是和该函数通过 wait(2) 系统调用返回的一样的退出状态。在传统的语意里,要获取实际的退出值,要除以 256 或者右移 8 位。这是因为低 8 位里有一些其他的东西。(实际上是其他的两些东西。)最低七位标识杀死该进程的信号号码(如果有的话),而第八位标识该进程是否倾倒了核心。你可以通过 $?($CHILD_ERROR)来检查所有失效可能性,包括信号和核心倾倒: $exit_value = $? & 127; # 或者 0x7f, 0177, 0b0111_1111 $dumped_core = $? & 128; # 或者 0x80, 0200, 0b1000_0000 如果该程序是通过系统 shell (注:定义为 /bin/sh 或者任何在你的平台上有意义的东西,但不是那些用户碰巧在某个时候用到的 shell。)运行的,这可能是因为你只有一个参数而且该参数里面有 shell 元字符,那么通常返回码受那个 shell 的怪癖和功能的影响。换句话说,在这种情况下,你可能无法获取我们前面描述了详细信息。 3. exec o exec PATHNAME LIST o exec LIST exec 函数结束当前程序的运行并且执行一条外部命令并且决不返回!!!如果你希望在该命令退出之后恢复控制,那么你应该使用 system。exec 函数只有在该命令不存在以及该命令是直接执行而没有通过你的系统的命令行 shell(下面讨论)执行的时候才失败并返回假。 下面这个例子显示了你可以 exec 一个流水线,而不仅仅是一个程序: or die "Can't do sort/uniq: $!\n"; 通常,exec 从不返回——就算它返回了,它也总是返回假,并且你应该检查 $! 找出什么东西出错了。要注意的是,在老版本的 Perl 里,exec(和 system)并不刷新你的输出缓冲,所以你需要在一个或更多个文件句柄上通过设置 $| 打开命令缓冲功能以避免在 exec 的情况下丢失输出,或者在 system 的情况下打乱了输出顺序。在 Perl 5.6 里情况大致如此。 exec $editor "view", @files # 触发只读模式 和任何其他间接对象一样,你也可以用一个包含任意代码的块代替上面这个保存程序名的简单标量,这样就可以把前面这个例子简化为: 如前所述,exec 把一个离散的参数列表当作一个它应该绕开 shell 处理的标志。不过,仍然有一个地方可能把你拌倒。exec 调用(以及 system)不能区别单个标量参数和一个只有一个元素的列表。 为了避免这种情况,你可以使用 PATHNAME 语法,明确地把第一个参数当路径名复制,这样就强制其他的参数解释成一个列表,即使实际上只有一个元素: 第一个没有花括弧的版本,运行 echo 程序,给它传递“surprise”做参数。第二个版本不是这样——它试图运行一个字面上叫 echo surprise 的程序,但找不到(我们希望如此),然后把 $! 设置为一个非零值以表示失败。 { exec ('foo') }; print STDERR "couldn't exec foo: $!"; 正如上面的第二行显示的那样,如果调用 exec 的时候是一个块里的最后一条语句,那么就可以免于警告。 |