crunchi has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use fork to perform a rather long task. The problem I'm having is that the child process doesn't seem to be able to access files. At least I think that's the problem. I fork using this code. It's not mine, I just grabbed it from somewhere... (die statements shortened for clarity...)
$SIG{CHLD} = 'IGNORE'; defined (my $kid = fork) or die "Cannot fork: $!\n"; if($kid) { # do nothing... } else { chdir '/webRoot/cgi-bin' or die ... open STDIN, '/dev/null' or die ... open STDOUT, '>/dev/null' or die ... open STDERR, '>/tmp/log' or die ... setsid or die ... my $oldfh = select STDERR; local $| = 1; select $oldfh; my $run = "perl /webRoot/apps/startPipe.pl -f $dest_file -j $job_ ++ID -c $created -t $job_type $adv_opts"; `$run`; CORE::exit(0); # terminate the process }
Then in the file startPipe.pl...
for my $i (1 .. 1) { $arab_string .= "my \@arab$i = ("; $blast_run = "blastn ATH1_chr$i.1con.01222004 $seq_file_name - +wa +rnings"; warn "$blast_run\n"; $blast_output = `$blast_run`; warn "Error: $!\n"; ...
and finally in the file /tmp/log
blastn ATH1_chr1.1con.01222004 /webRoot/cgi-bin/jobs/15-12-2007/WZuFQe + +miR8sSigXB3vFjLiuix/WZuFQemiR8sSigXB3vFjLiuix -warnings Error: No such file or directory
and if i copy the the string generated by $blast_run and paste it into bash it will work, the files are in the right places. I have chmodded everything to 777 to make sure that it's not permissions. I'm probably missing something very simple... Thanks.

Replies are listed 'Best First'.
Re: File Access for child process
by Anonymous Monk on Dec 21, 2007 at 02:02 UTC
    my $oldfh = select STDERR; local $| = 1; select $oldfh;

    This is superfluous as the STDERR stream is unbuffered.

    my $run = "perl /webRoot/apps/startPipe.pl -f $dest_file -j $job_ ++ID -c $created -t $job_type $adv_opts"; `$run`;

    You have forked a new process and now you are using backticks in void context which forks another process and starts a shell to run your command and returns the STDOUT of that command. Just use exec:

    exec 'perl', '/webRoot/apps/startPipe.pl', '-f', $dest_file, '-j', + $job_', '+ID', '-c', $created, '-t', $job_type, $adv_opts;
Re: File Access for child process
by almut (Canon) on Dec 20, 2007 at 23:49 UTC

    I would try specifying the full path to blastn — your webserver (although you're not explicitly talking of one, the 'webRoot' and 'cgi-bin' make me figure you're using one) might have a different search path configured as your interactive shell...  Just an idea.

Re: File Access for child process
by dwm042 (Priest) on Dec 21, 2007 at 16:16 UTC
    I have to agree with almut. If the code works fine entered manually, but not in a script, it's often a difference in the PATH environment variable.

    You can check this explicitly. Type:
    echo $PATH
    in your BASH shell and also add the line:

    print $ENV{"PATH"}, "\n";
    in your script just before the backticks.

      Thanks guys. I probably should have worked that one out myself. But I had been working on this baby for about 19 hours straight. I think I fried my brain...