End perl script without waiting for system call to return
The web server creates a pipe from which to receive the response. It waits for the the pipe to reach EOF before completing the request. A pipe reaches EOF when all copies of the writer handle are closed.
The writer end of the pipe is set as the child's STDOUT. That file handle was copied to be the shell's STDOUT, and again to the mycmd
's STDOUT. So even though the CGI script and the shell ended and thus closed their ends of the file handle, mycmd
still holds the handle open, so the web server is still waiting for the response to complete.
All you have to do with to close the last handle to the writer end of the pipe. Or more precisely, you can avoid making it in the first place by attaching a different handle to mycmd
STDOUT.
mycmd arg1 arg2 </dev/null >/dev/null 2>&1 &
How do I make a system call and resume execution without waiting for the call to return?
Short answer, no. This is the entire point of fork()
. The only question is whether you call fork()
directly, or get something else to do that for you.
As mentioned, you could use the shell's backgrounding operator (&
) to do that, but then you're using the shell, and that comes with the usual string-injection attack problem
system("some command with args &");
More directly, you could just do the usual fork()
and exec()
and then not perform the waitpid()
that normally happens, which is where the blocking occurs:
if(fork() == 0) {
exec("some", "command", "with", "args") or die "Cannot exec - $!";
}
# No waitpid here so no waiting
If you're doing that, best also to put a SIGCHLD
handler in to ignore when the child does eventually exit, so as not to leave zombies hanging around. At some point near the beginning of the code, put
$SIG{CHLD} = 'IGNORE';
Running job in the background from Perl WITHOUT waiting for return
Essentially you need to 'daemonize' a process -- fork off a child, and then entirely disconnect it from the parent so that the parent can safely terminate without affecting the child.
You can do this easily with the CPAN module Proc::Daemon:
use Proc::Daemon;
# do everything you need to do before forking the child...
# make into daemon; closes all open fds
Proc::Daemon::Init();
Is there a Perl function like 'system' that doesn't wait for a returned value?
An exec
within a fork
will work without blocking execution:
if (command is bla) {
exec "osascript 'something.app'" if fork;
} else {
print $client "invalid command\r\n";
}
How to run a script and not wait for it in Perl?
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 &');
}
Perl script is not waiting for a .bat file to complete and continuing execution
You need to remove the start
command
Without the /wait
option, start
will create a process and return immediately
But there is no need for start
at all. You can write just
system($bat_file);
to achieve the effect that you're asking for
I have a system call that somehow is causing malformed header from script Bad header
The system
command just doesn’t give you complete control over capturing STDOUT and STDERR of the executed command.
Use backticks or open
to execute the command instead. That will capture the STDOUT of the command’s execution. If the command also outputs to STDERR, then you can append 2>&1
to redirect STDERR to STDOUT for capture in backticks, like so:
my $output = `$command 2>&1`;
If you really need the native return status of the executed command, you can get that information using $?
or ${^CHILD_ERROR_NATIVE}
. See perldoc perlvar
for details.
Another option is to use the IPC::Open3
Perl library, but I find that method to be overkill for most situations.
Related Topics
Open Website from Within Eclipse's Internal Browser
How to Set Umask Default for an User
Kernel Oops Page Fault Error Codes for Arm
Is There Any General Interfaces on Linux to Simulate Mouse Movements and Click
"Segmentation Fault (Core Dumped)" Error in Fortran Gfortran Linux
Running Linux Container on Docker Windows
Setting Path to Shared Library Inside a Makefile for Compile
Is There a Linker Flag to Force It to Load All Shared Libraries at Start Time
Tensorflow Recommended System Specifications
Finding Processor Id in Which Process Is Running [Through Command/Interface Similar to Top]
Windows <Sys/File.H> Equivalent
How to Schedule a Cron for The First Thursday of Every Month
Ansible - Winrm or Requests Is Not Installed
Whats The Easiest Way to Send Messages to My Linux Daemon App
How to Make 'Docker Run' Inherit Ulimits
How to Get Wget Only Save File If Its Complete
Linux Mail Adding Content Type Headers Not Working
How to Automatically Start an Application That Needs X in Linux