1

Update: This has been resolved for system() and backticks by specifying the full path to the external script. I will further investigate the fork issue on my own. Thanks to all for assisting.

At How do I run a Perl script from within a Perl script? one answer offers either of these two methods of calling an external Perl script to run asynchronously:

`myscript.pl &`

system ('myscript.pl &')

I have tried using both of these in my main CGI script, but neither of them will execute the external script, although I can execute the external script successfully from the web browser. The external script is just a test to print a "hello" to the screen and to open an output text file with a timestamp and a hello in its content.

I don't doubt the validity of these suggested methods, but perhaps the virtual web hosting service I use (some sort of Unix on Apache server) is configured not to allow them (?) I have no idea why these don't work for me. If anyone knows, the insight would be appreciated.

Moving on, though, the reason I am looking at these two methods is that the web hosting service told me that I should not use forking, saying that "Forking is a complicated process that requires extensive knowledge, and CGI scripts are not true processes...you are asking for trouble if you fork in your CGI scripts."

In fact, I had already built a CGI script that used fork() and exec() to process multiple external jobs simultaneously. However, I'd also discovered that -- after some random number of forks (e.g. after 15-17 fork iterations in the exact same foreach loop) -- Perl started assigning the parent process ID as a new child process ID (as though it was recycling the main process in mid process?), which caused the main script to exec and thereby kill itself. I was only asking the hosting service how that could possibly be happening. That was their answer, so I figure I'd better not do what they advised against.

Without forking, I'm at a loss as to what I can do if the two above mentioned methods are simply not doing anything.

  • "*.. but neither of them will execute"*: What is the return value when you call `system()` ? – Håkon Hægland Dec 13 '20 at 08:10
  • *"Perl started assigning the parent process ID as a new child process ID"* - I would assume that this is either a wrong observation or misinterpretation or a bug in your (unknown) script . It is not up to Perl to assign process id anyway, this is done by the underlying OS. And the OS does not assign a process id twice, i.e. it is impossible to have two processes with the same pid at the same time. – Steffen Ullrich Dec 13 '20 at 09:47
  • 1) "not doing anything" is not an adequate description of the problem. 2) `backticks` uses `fork`. `system` might too. 3) Perl doesn't assign PIDs, the OS does. And the OS won't assign a PID that's currently in use. 4) `system` and backticks work perfectly fine, though the `... &` commands will only work on a unix system. 5) Will using `... &` work correctly if you don't daemonize? – ikegami Dec 13 '20 at 10:27
  • @SteffenUllrich Okay, Steffen. You and igekami are both saying it's impossible for the parent ID to be re-assigned as a forked child process, so I will re-examine the returned process IDs in a simpler forking script context to rule out anything I didn't see before as the cause. – user10823099 Dec 14 '20 at 07:55
  • @igekami The system and backticks calls required that I use the full path to the external script, even though it was in the same directory, I discovered. Yes, with the ... & included. Right, system definitely uses fork according to the Perl documentation, but I was looking for a way not to do forks explicitly. Daemonizing is beyond my scope of understanding, but my issue seems to be resolved with the backticks and system calls. I will look deeper into what my problem with fork might have been. Thanks for responding too. – user10823099 Dec 14 '20 at 08:06

1 Answers1

0

I tested this with the XAMPP Apache distribution on Ubuntu 20.04:

use feature qw(say);
use strict;
use warnings;
use CGI;

my $cgi = CGI->new();
print $cgi->header( -type => 'text/plain' );
my $res = system "date";
say "system('date') returned value: $res";
my $date = qx'date';
say "The date is: $date";
exit;

and it works fine here. The output in the browser is:

Sun Dec 13 09:18:25 CET 2020
system('date') returned value: 0
The date is: Sun Dec 13 09:18:25 CET 2020
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 1
    Hi Håkon. Thanks for going to the trouble of checking that. The return value of system was "0", despite the fact that it was not executing the external script. I then tried using the full path to the Perl script and it worked. I then tried the full path with the backticks and that also worked. As the external Perl script is in the same directory as the calling script, I'd assumed it wouldn't need to see the full path, but apparently it does. I guess that the system() and backticks calls use a different point of reference in relation to external files. – user10823099 Dec 14 '20 at 07:48
  • Great! Maybe related: [Doesn't Perl include current directory in @INC by default?](https://stackoverflow.com/q/46549671/2173773) – Håkon Hægland Dec 14 '20 at 07:50