如何在Perl中运行脚本而不是等待它?

时间:2011-09-12 17:03:11

标签: perl cross-platform platform-independent

我在Perl中有一个系统调用,如下所示:

system('/path/to/utility >> /redirect/to/log file');

但这等待utility完成。我只想触发这个并让Perl脚本完成,无论utility调用是否完成。

我该怎么做?

我尝试将线路更改为

system('/path/to/utility >> /redirect/to/log file &');

但是这个语法仍然等待在Windows上完成调用。我需要让它在Linux和Windows上运行。

4 个答案:

答案 0 :(得分:7)

if ($^O eq 'MSWin32') {
   system('start "" \\path\\to\\utility >> \\redirect\\to\\log_file');
} else {
   system('/path/to/utility >> /redirect/to/log_file &');
}

if ($^O eq 'MSWin32') {
   system(1, '\\path\\to\\utility >> \\redirect\\to\\log_file');
} else {
   system('/path/to/utility >> /redirect/to/log_file &');
}

答案 1 :(得分:2)

您可以尝试查看fork关键字,然后从分叉进程启动系统命令。有关示例,请参阅perlipc联机帮助页。

答案 2 :(得分:2)

类似POSIX的系统上最简单的方法实际上是你已经尝试过的方法:

system('/path/to/utility >> /redirect/to/log_file &');

让Windows工具在后台执行的最简单方法是使用start.exe作为启动助手:

system('start /path/to/utility >> /redirect/to/log_file');

但是,我不知道它是否能够将输出重定向到日志文件,并且我现在没有Windows系统来测试它。

是的,这意味着您需要一个代码分支,具体取决于当前系统,但其他解决方案也可能需要。如果您的Perl具有fork()仿真,您实际上可以在两个系统上使用fork()(这有点复杂,因为您无法将stdout重定向到容易的日志文件,您首先必须在Perl并在调用新进程之前使其成为分叉子进程的stdout)。如果您的Windows Perl没有fork()仿真,那么您还需要一个代码分支,因为在这种情况下,您只能在UNIX上使用fork(),并且您需要将Win32::Process::Create与{一起使用} Windows上的{1}}选项。

但也许您可以先告诉我们使用start是否已经为您服务。如果没有,可能DETACHED_PROCESS不处理斜杠。在这种情况下,您可能必须使用类似

的内容
start.exe

相反(双反斜杠很重要!单个反斜杠在字符串文字中有特殊含义;它是转义字符。)

要了解您是否在Windows上运行,请查看变量C:\\path\\to\\utility $OSNAME,它应该在Windows上说“MSWin32”。

答案 3 :(得分:2)

此常见任务已被抽象到CPAN模块Proc::Background