PDA

View Full Version : Perl Email Command Line



nsilva
April 29th, 2007, 06:57 AM
For a long I have been wanting to run some commands in my server while Im away, far from a computer.
http://www.linuxjournal.com/article/6453

I found this article, little bit outdated, but the principles still hold. I followed the tutorial and use the script the author suggests for processing emails from procmail



nsilva@typhon:~$ cat /home/nsilva/bin/console.pl
#!/usr/bin/perl
use IPC::Open3;
use Symbol;
#-----------------------
# setup vars for open3
#-----------------------
$WTR = gensym();
$RDR = gensym();
$ERR = gensym();
#---------------------------
# some handy variable defs
#---------------------------
$logfile = "/home/nsilva/e-mail_console.log";
$line_sep = 0;
$separator = "\n" . "~" x 72 . "\n";
$theOutput = "\n\n";
$reply_subject = "E-mail Console Results";
$signature_line = "\n--\nOutput generated by the E-mail Console\n";
$no_commands_mesg = "No commands found to execute.";
$from = "";
$reply_to = "";
#---------------
# open log file
#---------------
open LOG, "<<$logfile";
#--------------------------
# our parse/execution loop
#--------------------------
while(<>) {
#------------------------
# get the sender address
#------------------------
if ( $_ =~ m/From: (.*)/) {
$from = $1;
}
#---------------------------------
# get the sender address override
#---------------------------------
if ( $_ =~ m/Reply-To: (.*)/) {
$reply_to = $1;
}
#---------------------------
# look for <exec>...</exec>
# and process the command
#---------------------------
if ( $_ =~ m/^<exec>(.*)<\/exec>/ ) {
undef $cmd_output;
if ($line_sep) {
$theOutput .= $separator;
} else {
$line_sep = 1;
}

$who = ($reply_to ne "") ? "F:$from R:$reply_to" : $from;
print LOG scalar localtime() . " $who executed [$1]\n";
$theOutput .= "Executing [$1]\n\n";
#-----------------------
# execute the command(s)
#-----------------------
open3($WTR, $RDR, $ERR, $1);
close($WTR);
while (<$RDR>) {
$cmd_output .= $_;
}

while (<$ERR>) {
$cmd_output .= $_;
}

$theOutput .= $cmd_output;
}
}
#-----------------------------
# report if there were
# no command executed at all
#-----------------------------
if (!$line_sep) {
$theOutput .= $no_commands_mesg;
}
#---------------------------
# tack on a handy dandy
# signature line
#---------------------------
$theOutput .= $signature_line;
#-----------------------------
# override the from address
# with the reply-to address
#-----------------------------
if ($reply_to ne "") {
$from = $reply_to;
}
#----------------------
# close the log file
#----------------------
close LOG;
#-----------------------
# send the reply e-mail
# with the execution
# results
#-----------------------
exec "echo \"$theOutput\" | mailx -s \"$reply_subject\" \"$from\"";
exit;


The script works well when I try normal system commands. I design one script that I need to execute continously but it is giving me weird answers

This is the script I want to execute from the email


nsilva@typhon:~$ cat bin/mort.php
#!/usr/bin/php -q
<?php
array_shift($_SERVER["argv"]);
if (count($_SERVER["argv"])==0) {
print "Insufficient Inputs Provided";
print "Usage mort [Loan Total] [# Years] [Type of Loan (100 or 80/20)] [Interest Rate 1] ";
print "[InterestRate 2] [State 2 Letters for Closing Cost]\n";
print "Ex:\n";
print "mort 250,000 60 80 7% 9% MD \n";
terminate;
}

//Collet Inputs from CLI
$principal = $_SERVER["argv"][0];
$periods = $_SERVER["argv"][1]*12;

$loanamt[0] = $principal*$_SERVER["argv"][2]/100;
$interest[0]= $_SERVER["argv"][3]/100;

if ($_SERVER["argv"][2] < 100)
{
$loanamt[1] = $principal*(100-$_SERVER["argv"][2])/100;
$interest[1] = $_SERVER["argv"][4]/100;
}

for ($counter = 0; $counter <= 1; $counter += 1) {
$payment[$counter] = PaymentCalc(12,$periods,$interest[$counter],$loanamt[$counter]);
}

echo "Output \n";
echo "---------------\n";
if ($_SERVER["argv"][2] < 100){
echo "Big Loan-> Principal: $$loanamt[0] @ " . $interest[0]*100 . "% - Payment: $$payment[0] \n";
echo "Small Loan-> Principal: $$loanamt[1] @ " . $interest[1]*100 . "% - Payment: $$payment[1]\n";
echo "Total Payment: $";
echo $payment[0]+$payment[1];
} else {
echo "Loan-> Principal: $$loanamt[0] @" . $interest[0]*100 . "% - Payment: $$payment[0]";
}


// Given the compounding, principal, interest rate, you can calculate the monthly payment

$m = 12; //12 Periods in a year
function PaymentCalc ($m,$n,$R,$principal) {
$Z = 1 / (1 + ($R/$m));
return ((1 - $Z) * $principal) / ($Z * (1 - pow($Z,$n)));
}

?>

nsilva@typhon:~$



When I run it from the CLI

nsilva@typhon:~$ /home/nsilva/bin/mort.php 19000 30 100 10 10


and I get the following output

nsilva@typhon:~$ /home/nsilva/bin/mort.php 19000 30 100 10 10

Warning: Division by zero in /home/nsilva/bin/mort.php on line 47
Output
---------------
Loan-> Principal: $19000 @10% - Payment: $166.738598317
nsilva@typhon:~$


but in the email I get something, completely different,

Executing [ /home/nsilva/bin/mort.php 19000 30 100 8 7 ]


Warning: Division by zero in /home/nsilva/bin/mort.php on line 47
Output
---------------
Loan-> Principal: @8% - Payment: .415269037

--
Output generated by the E-mail Console

I know is a little bit overwelming, but I can not make sense of where the error is coming from, In addition, to the fact that Perl is not my streght.

I appreciate some help

yaaarrrgg
April 30th, 2007, 05:26 PM
you probably need to check the math in the part (it says you are dividing by zero ... ):



$m = 12; //12 Periods in a year
function PaymentCalc ($m,$n,$R,$principal) {
$Z = 1 / (1 + ($R/$m));
return ((1 - $Z) * $principal) / ($Z * (1 - pow($Z,$n)));
}


to debug, you might echo these vars out, rather than actually performing the calculations. you might also need to correct the calculation, or add a specific check before doing it (that the denominator is not 0)