我在Perl中有一个系统调用,如下所示:
system('/path/to/utility >> /redirect/to/log file');
但这等待utility
完成。我只想触发这个并让Perl脚本完成,无论utility
调用是否完成。
我该怎么做?
我尝试将线路更改为
system('/path/to/utility >> /redirect/to/log file &');
但是这个语法仍然等待在Windows上完成调用。我需要让它在Linux和Windows上运行。
答案 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