user26241
user26241

Reputation: 91

how to redirect this perl script's output to file?

I don't have much experience with perl, and would appreciate any/all feedback....

[Before I start: I do not have access/authority to change the existing perl scripts.]

I run a couple perl scripts several times a day, but I would like to begin capturing their output in a file.

The first perl script does not take any arguments, and I'm able to "tee" its output without issue:

/asdf/loc1/rebuild-stuff.pl 2>&1 | tee $mytmpfile1

The second perl script hangs with this command:

/asdf/loc1/create-site.pl --record=${newsite} 2>&1 | tee $mytmpfile2

FYI, the following command does NOT hang:

/asdf/loc1/create-site.pl --record=${newsite} 2>&1

I'm wondering if /asdf/loc1/create-site.pl is trying to process the | tee $mytmpfile2 as additional command-line arguments? I'm not permitted to share the entire script, but here's the beginning of its main routine:

...
my $fullpath = $0;
$0 =~ s%.*/%%;

# Parse command-line options.
...
Getopt::Long::config ('no_ignore_case','bundling');
GetOptions ('h|help'               => \$help,
            'n|dry-run|just-print' => \$preview,
            'q|quiet|no-mail'      => \$quiet,
            'r|record=s'           => \$record,
            'V|noverify'           => \$skipverify,
            'v|version'            => \$version) or exit 1;
...

Does the above code provide any clues? Other than modifying the script, do you have any tips for allowing me to capture its output in a file?

Upvotes: 1

Views: 461

Answers (1)

ikegami
ikegami

Reputation: 386561

It's not hanging. You are "suffering from buffering". Like most programs, Perl's STDOUT is buffered by default. Like most programs, Perl's STDOUT is flushed by a newline when connected to a terminal, and block buffered otherwise. When STDOUT isn't connected to a terminal, you won't get any output until 4 KiB or 8 KiB of output is accumulated (depending on your version of Perl) or the program exits.

You could add $| = 1; to the script to disable buffering for STDOUT. If your program ends with a true value or exits using exit, you can do that without changing the .pl file. Simply use the following wrapper:

perl -e'
   $| = 1;
   $0 = shift;
   do($0);
   my $e = $@ || $! || "$0 didn\x27t return a true value\n";
   die($e) if $e;
' -- prog args | ...

Or you could fool the program into thinking it's connected to a terminal using unbuffer.

unbuffer prog args | ...

Upvotes: 5

Related Questions