Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在perl脚本中执行unix命令并检查是否失败的最佳方法_Perl - Fatal编程技术网

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

在perl脚本中执行unix命令并检查是否失败的最佳方法,perl,Perl,我想在perl中执行几个unix命令。最好的方法是什么? 使用qx还是系统更好?有没有好办法检查它是否失败?有人能给我举个好例子吗?谢谢 my $crflag=qx('/bin/touch /tmp/flag.done'); my $chgperm=qx('chmod 755 /tmp/flag.done'); vs 与$?一起使用?。当不需要输出时,尽量避免使用qx system '/bin/touch /tmp/flag.done'; my $touch_status = $? >&

我想在perl中执行几个unix命令。最好的方法是什么? 使用qx还是系统更好?有没有好办法检查它是否失败?有人能给我举个好例子吗?谢谢

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

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

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

system 'chmod 755 /tmp/flag.done';
my $chmod_status = $? >> 8;
与$?一起使用?。当不需要输出时,尽量避免使用qx

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

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

您的代码有几个问题:

您似乎不需要输出,这意味着您需要系统,但这些步骤非常简单,可能应该直接在Perl中完成,而不是调用shell。在Perl 2中,touch实际上是一个调用,如果您计算关闭文件的次数。 有一个竞争条件,因为您正在创建文件,然后分两步设置其权限。由于这看起来像一个标志文件,所以竞争条件似乎是相关的,因此您可能希望在一个命令中使用原子create/setperms。 由于它是一个标志文件,您可能需要模式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 out以创建文件然后重置其权限之间发生干扰。仍然存在同步方面的问题,因此它仍然可能被抢占,但总体而言,这是一个更好的解决方案


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

您的代码有几个问题:

您似乎不需要输出,这意味着您需要系统,但这些步骤非常简单,可能应该直接在Perl中完成,而不是调用shell。在Perl 2中,touch实际上是一个调用,如果您计算关闭文件的次数。 有一个竞争条件,因为您正在创建文件,然后分两步设置其权限。由于这看起来像一个标志文件,所以竞争条件似乎是相关的,因此您可能希望在一个命令中使用原子create/setperms。 由于它是一个标志文件,您可能需要模式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 out以创建文件然后重置其权限之间发生干扰。仍然存在同步方面的问题,因此它仍然可能被抢占,但总体而言,这是一个更好的解决方案


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

除了这两个操作都可以使用内置的utime和chmod轻松完成之外,还提供了错误检查

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

除了使用内置的utime和chmod可以轻松完成这两个操作之外,还提供了错误检查

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

谢谢你的意见。我打印了$touch_status和$chmod_status,两者都返回0,这意味着没有错误。为了检查是否成功,我会做一些类似于$touch_status==0{print flag已设置;}的事情吗?我会说我们使用IPC::run获得了更好的控制谢谢您的输入。我打印了$touch_status和$chmod_status,两者都返回0,这意味着没有错误。为了检查是否成功,我会做一些类似于$touch_status==0{print flag已设置;}的事情吗?我会说我们使用IPC获得了更好的控制:Run@Sdaz-谢谢你的回复。我不熟悉Fnctl,我正在查找这个。在某个时刻,该标志将从一个单独的程序中读取,作为启动其进程的指示器。是的,它只是一个标志文件。Fcntl就在那里,因为它导出了常量O_CREAT、O_EXCL等。sysopen是一个核心perl函数,没有它也可以使用,但是它更容易与常量一起使用。以上应该让你开始;但是请注意,如果文件已经存在,O_EXCL不会覆盖该文件;如果你想让它可以,就把它扔掉。sysopen下的perldoc perlopentut中的描述可能更全面地描述了每个常量的作用。@Sdaz-感谢您的回复。我不熟悉Fnctl,我正在查找这个。在某个时刻,该标志将从一个单独的程序中读取,作为 启动它的进程。是的,它只是一个标志文件。Fcntl就在那里,因为它导出了常量O_CREAT、O_EXCL等。sysopen是一个核心perl函数,没有它也可以使用,但是它更容易与常量一起使用。以上应该让你开始;但是请注意,如果文件已经存在,O_EXCL不会覆盖该文件;如果你想让它可以,就把它扔掉。sysopen下perldoc perlopentut中的描述可能更全面地描述了每个常量的作用。