在perl脚本中执行unix命令的最佳方法,并检查它是否失败

时间:2011-03-08 05:13:10

标签: perl

我想在perl中执行几个unix命令。最好的方法是什么? 使用qx或system()更好吗?有没有一种好方法可以检查它是否失败?有人能给我一个很好的例子吗?感谢。

my $crflag=qx('/bin/touch /tmp/flag.done');
my $chgperm=qx('chmod 755 /tmp/flag.done');

VS

my $crflag = '/bin/touch /tmp/flag.done';
my $chgperm ='chmod 755 /tmp/flag.done';
system ($crflag);
system ($chgperm);

3 个答案:

答案 0 :(得分:5)

您的代码存在一些问题:

  • 您似乎不想要输出,这意味着您需要system,但这些步骤非常简单,可能应该直接在Perl中完成,而不是调用shell。 touch在Perl中实际上是1次调用(如果你计算关闭文件,则为2次。)
  • 存在竞争条件,因为您正在创建文件,然后分两步设置其权限。由于这看起来像一个标志文件,因此竞争条件似乎相关,因此您可能希望在一个命令中使用原子创建/设置。
  • 由于它是一个标志文件,您可能需要模式0644而不是0755

在Perl中,您可以使用以下内容解决上述所有问题:

#!/usr/bin/perl

use Fcntl qw( :DEFAULT );   # Core module, for O_CREAT, etc. constants
use strict;
use warnings;

# You probably want 0644, as a flag file probably shouldn't be executable..?
sysopen( my $fh, '/tmp/flag.done', O_CREAT|O_EXCL|O_RDWR, 0644 )
# Sysopen returns a undef if unsuccessful, with an error message stored in $!
    or die "$!";
# write to it here, if you need to.
close( $fh );

你可以将它放入一个sub中,你想要创建一个(更多)原子创建步骤,以避免其他进程在大量shell调用之间干扰两次以创建文件,然后重置其权限。 (仍然存在对同步的担忧,因此它仍然可以被抢占,但这总体上是一个更好的解决方案。)

您可能希望使用其他标志。检查perldoc perlopentut并搜索sysopen以获取一个小列表,或查看perldoc Fcntl和您平台的文档以获取更全面的列表。您可能还希望将0644权限更改为更严格的限制,并且您可能还希望使用锁定;有关建议锁定的信息和代码示例,请参阅perldoc -f flock

答案 1 :(得分:4)

除了使用内置utimechmod可以轻松完成这两项操作之外,IPC::System::Simple还提供错误检查。

use IPC::System::Simple qw( system );
system('/bin/touch /tmp/flag.done');
system('chmod 755 /tmp/flag.done');

答案 2 :(得分:2)

使用system$?。当不需要输出时,尽量避免使用qx

system '/bin/touch /tmp/flag.done';
my $touch_status = $? >> 8;

system 'chmod 755 /tmp/flag.done';
my $chmod_status = $? >> 8;