Question

I have a system call in Perl that looks like this:

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

But this waits for utility to complete. I just want to trigger this and let the Perl script finish irrespective of whether the utility call finished or not.

How can I do this?

I tried changing the line to

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

but this syntax still waits for the call to finish on Windows. I need to make it work on Linux as well as Windows.

Was it helpful?

Solution

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

or

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

OTHER TIPS

You could try looking at the fork keyword, and launch your system command from the forked process. See the perlipc manpage for examples.

This common task has been abstracted into the CPAN module Proc::Background

The easiest way on POSIX-like systems is in fact the one you already tried:

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

The easiest way to get a tool to execute in background on Windows is to use start.exe as a launch helper:

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

However, I don't know if it works to redirect the output to log file that way and I have no Windows system around this very moment for testing it.

Yes, that means you would need a code branch depending on current system, but other solutions may need one, too. If your Perl has fork() emulation, you can in fact use fork() on both systems (this is a bit more complicated, since you cannot redirect stdout to a logfile that easy, you first have to open it in Perl and make it stdout of the forked child before calling the new process). If your Windows Perl has no fork() emulation, you also need a code branch, since in that case you can use fork() only on UNIX and you'll need to use Win32::Process::Create with the DETACHED_PROCESS option on Windows.

But maybe you can first let us know if using start is already working for you. If it does not, maybe start.exe doesn't handle slashes. In that case you may have to use something like

C:\\path\\to\\utility

instead (double backslash is important! A single backslash has a special meaning in string literals; it's the escape character).

To find out if you are running on Windows or not, take a look at the variable $OSNAME or $^OS, it should say something like "MSWin32" on Windows.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top