User Tools

Site Tools


doc:appunti:prog:perl_program_execution

Program execution from Perl

system()

With the system() function a process is forked to execute the system command, and the main program waits for the child process to return. The output is displayed to the screen (STDIN, STDOUT, STDERR are connected to the parent process?). The function returns the exit code and which signal, if any, the process died from.

$cmd = "tar zcf '$opt_f' -C '$tmp_dir' .";
print "$cmd\n" if ($debug);
$ret = system($cmd);
print "system() funct returned " . ($ret)        . "\n";
print "child died on signal "    . ($ret & 0xff) . "\n";
print "child exit code was "     . ($ret >> 8)   . "\n";

Executing a chain of commands

The following is a more complicated example. A local_command is executed, its output is piped through ssh to a remote host, where a remote_command is launched:

$cmd  = "local_command";
$cmd .= " | ssh -o StrictHostKeyChecking=no -p ${REMOTE_PORT} ${REMOTE_USER}\@${REMOTE_HOST}";
$cmd .= " remote_command";
$ret = system($cmd);
print "system() funct returned " . ($ret)        . "\n";
print "child died on signal "    . ($ret & 0xff) . "\n";
print "child exit code was "     . ($ret >> 8)   . "\n";
  • STDOUT of local_command is piped to STDIN of remote_command
  • STDERR of local_command is piped to STDERR of Perl
  • STDOUT and STDERR of ssh are piped to Perl
  • STDOUT and STDERR of remote_command are piped to Perl
  • The child exit code is the exit code of ssh (which, in turns, should be the exit code of remote_command)

If an error occurrs in local_command, it gets unnoticed unless remote_command fails too.

back quotes operator

Also known as the qx// operator. You can actually use any set of delimiters, not just the slashes or the parenthesis. It returns the STDOUT of the executed command, that can be captured into an array. The STDERR of the executed command is connected to STDERR of the perl program. The exit code of the executed command can be retrieved with the $? special variable ($CHILD_ERROR variable). A process is forked to execute the system command and the main perl program waits for the child process to return. The $? variable is actually the exit code of the wait() system call, it contains the exit code and which signal, if any, the process died from.

$cmd = "du -s /tmp";
@output = `$cmd`;
$ret = $?;
print "back quotes returned " . ($ret)        . "\n";
print "child died on signal " . ($ret & 0xff) . "\n";
print "child exit code was "  . ($ret >> 8)   . "\n";

fork()

If you want to execute an external program and let the main program to continue, you have to fork(). This is equivalent to the fork() Unix system call; after the call you have two identical process running, the only difference is the value returned by the function: 0 in the child, the PID of the child in the parent:

if (($pid = fork()) == 0) {
    # Here it is the child running.
    $cmd = "ls -l";
    system($cmd);
    exit(0);
}
# Here it is che parent running.
print "Child process is running with PID $pid\n";

Exiting from a Perl program

die()

With the die() function:

die("Statement failed with error ${code}. Stopped") if ($code != 0);

The argument of the die() function will be printed to STDERR. If the string does not end with a newline, the the program name and line number where the error occurred will be appended:

Statement failed with error 1. Stopped at ./perl_example line 59.

The exit code is the current value of $! ($OS_ERROR) which may have been set by a previous function. If $! has a value of zero, $? ($CHILD_ERROR) will be returned instead. If $? is zero, it exits with an exit value of 255.

exit()

This function evaluates the expression given as an argument and exits the program with that value as the exit code. The default value for the exit code is 0 if no argument is supplied. If an END block has been defined, it will be called. Also, object destructors may be called before the process truly ends.

doc/appunti/prog/perl_program_execution.txt · Last modified: 2007/01/17 17:52 by 127.0.0.1