0

If I run a perl program and call another perl program using backquotes, print statements from the called program don't appear at the terminal.

If I call the program using 'system', the print statements are displayed.

EG: This is ProgA.pl

print "In ProgA.pl, about to call ProgB.pl";
my $dum=`ProgB.pl`;                       # print output doesn't appear
### $dum=system("ProgB.pl");              # this prints OK
print"\nBack in ProgA.pl";
print "\ndum = $dum";             # ProgB's output doesn't show here either

(No warnings or errors, perl.exe found through file association)

This is ProgB.pl:

print "\nPrinting from ProgB.pl";

What is the reason for the difference?

Why isn't the backquoted call output returned in $dum (I tried both STDOUT and STDERR)? If I call dir in backquotes, I get its output in $dum.

user1067305
  • 3,233
  • 7
  • 24
  • 29
  • You are right to expect it to wind up in `$dum` -- it should; that `print` in `ProgB.pl` goes to `STDOUT`, so it should end up in `$dum`. There is something else, not shown. Can you show complete programs, or at least more if they are too large? – zdim Jan 18 '18 at 06:42
  • 1
    That's what backticks do -- they capture whatever the other program printed into a variable so it's not shown (until perhaps you decide to print the variable yourself). But calling Perl from Perl seems like a poor way to arrange things anyway. Can you turn the other program into a module you can load into your program instead? – tripleee Jan 18 '18 at 06:49
  • These are the entire programs, written just to isolate the problem. The original programs are a couple of thousand lines. The reason I'm calling the perl program from perl is I'm trying replace batch files with perl. The reason I don't have both programs in one file is that I'm trying to keep them modular for use in other combinations. The called program then constructs, writes out, and executes, with backquotes, an html/js program to display the results. – user1067305 Jan 18 '18 at 07:51
  • Thanks for clarification -- entire programs, eh? That's a bit of a mystery then. On the practical side, you can use a module to run the other script, not backticks. If `system` can find/run the B script a module will as well (that's what they mostly use). Some good ones are [Capture::Tiny](http://search.cpan.org/~dagolden/Capture-Tiny-0.46/lib/Capture/Tiny.pm) and [IPC::Run3](http://search.cpan.org/~rjbs/IPC-Run3-0.048/lib/IPC/Run3.pm). – zdim Jan 18 '18 at 08:18
  • Another way around may be to use piped `open`. Btw, did you look at error variables, `$?` to start with? Perhaps backticks is failing for some B-file-related reason, which `system` figures out. – zdim Jan 18 '18 at 08:24
  • 1
    `\n` are traditionally meant to be printed at the end of a line, not the beginning – Chris Turner Jan 18 '18 at 10:45

2 Answers2

2

You have a path issue.

It works as expected ($dum is assigned the value "Printing from ProgB.pl") if I change the backticks from ProgB.pl to ./ProgB.pl. Without the explicit ./ path, it searches the system path and generates an error, as you can see if you change that line to

my $dum=`ProgB.pl` or die $!;

Which generates the output

In ProgA.pl, about to call ProgB.plNo such file or directory at ./ProgA.pl line 4.

Thus illustrating once again that you should always check the return values of your system calls for error conditions.

Dave Sherohman
  • 45,363
  • 14
  • 64
  • 102
  • "_illustrating once again that you should always check_" ... yeah – zdim Jan 18 '18 at 17:44
  • Thanks, but I don't get your results at all. If I add the 'die $!' it is not executed. If I add the './' I get the error 'In ProgA.pl, about to call ProgB.pl'.' is not recognized as an internal or exter nal command, – user1067305 Jan 18 '18 at 18:24
  • What environment and perl version are you working with? I got these results with Perl 5.20.2 under Debian. Are you maybe working in Windows? This seems like the sort of thing that might be a Linux/Windows difference. – Dave Sherohman Jan 19 '18 at 09:50
1

It appears that by failing to put a newline character at the end of the print command in ProgB, I failed to flush the buffer before returning to ProgA. Thanks to Chris Turner.

user1067305
  • 3,233
  • 7
  • 24
  • 29
  • 1
    fyi: I can't get backticks to behave this way no matter what I try. I suspect that there is more behind this and would still recommend to switch to a module. – zdim Jan 18 '18 at 20:35
  • Yeah. Like zdim, I tried moving the newlines around and the behavior remained consistent, too. – Dave Sherohman Jan 19 '18 at 09:36