7

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

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

但这等待utility完成。我只想触发它并让 Perl 脚本完成,而不管utility调用是否完成。

我怎样才能做到这一点?

我尝试将线路更改为

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

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

4

4 回答 4

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 &');
}
于 2011-09-12T17:38:05.323 回答
2

您可以尝试查看fork关键字,然后从分叉的进程中启动您的系统命令。有关示例,请参见perlipc手册页。

于 2011-09-12T17:07:43.593 回答
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()在两个系统上使用(这有点复杂,因为您不能将标准输出重定向到一个日志文件那么容易,您首先必须在 Perl 中打开它并使其成为分叉子的标准输出调用新进程)。如果您的 Windows Perl 没有fork()仿真,您还需要一个代码分支,因为在这种情况下您fork()只能在 UNIX 上使用,并且您需要在 Windows 上使用Win32::Process::CreateDETACHED_PROCESS选项。

但也许您可以先让我们知道使用 start 是否已经为您工作。如果没有,可能start.exe不处理斜线。在这种情况下,您可能必须使用类似的东西

C:\\path\\to\\utility

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

要确定您是否在 Windows 上运行,请查看变量$OSNAMEor $^OS,它应该在 Windows 上显示类似“MSWin32”的内容。

于 2011-09-12T17:57:16.713 回答
2

这个常见的任务已经被抽象到 CPAN 模块中Proc::Background

于 2011-09-12T19:48:14.120 回答