0

I need my script to do a simple operation:

  1. Use unix script command to log the activities on the screen to a file
  2. execute a shell script ( there are multiple lines output by this script to STDOUT)
  3. Stop the script command
  4. Analyse the output of the script command

I am planning to use system command to do this work, but I am not sure if I should fork the shell script and wait for its completion. Since the output of the shell script is multiple like not sure if capture will work. Let me know the best option

RobEarl
  • 7,862
  • 6
  • 35
  • 50
  • You have to execute the shell script from the shell which the `script` command invokes if you want to capture its output. Alternatively redirect stdout and stderr to a file instead of using `script`. – cdarke May 30 '13 at 16:27

2 Answers2

0

This is one of the most interesting questions I've come across in a while.

Let's say you have a shell script myscript.sh. To get script to run it and capture the output, at least on my SUSE linux, so check your script(1) man page, I'd write:

    script -c /path/to/myscript.sh myscript.log

So the Perl would look vaguely like:

# first, a bunch of code to initialize the program

# then run the shell script.
my $rv = system("script -c /path/to/myscript.sh myscript.log");

# then a bunch of code to process myscript.log

But I'm wondering my you can't just:

 system("/path/to/myscript.sh > myscript.log");

instead of involving script(1)?

Len Jaffe
  • 3,442
  • 1
  • 21
  • 28
0

Why do you need to use script at all? Is the shell script interactive? Does it need a valid TTY? If it is a non-interactive batch job that doesn't need a valid TTY, then you'd be best off opening it as a pipe and processing the output via a file handle.

For example:

open my $cmd_handle, "-|", $command, @args 
    or die "Could not run $command @args: $!";

foreach my $line ( <$cmd_handle> )
{
    # ... process the command output here ...
}

close $cmd_handle;

This has the advantage that your Perl script will process the command's output as it happens. In case you really do need to defer processing until the end, you could slurp all the output into an array and then process it afterwards:

open my $cmd_handle, "-|", $command, @args 
    or die "Could not run $command @args:  $!";

my @cmd_output = ( <$cmd_handle> );
close $cmd_handle;

foreach my $line ( @cmd_output )
{
    # ... process the command output here ...
}

Either ought to be better than running the command via script if it meets those restrictions I gave above: non-interactive, and does not need a valid TTY. Most batch scripts meet those restrictions.

Joe Z
  • 17,413
  • 3
  • 28
  • 39