tags:

views:

53

answers:

1

I've written a wrapper program for mailx using perl that allows me to easily add attachments and do some other nifty things that were a little frustrating to accomplish with mailx.

In the first few lines I have:

use strict;
use warnings;
use Getopt::Long;

my ( $to, $from, $subject, $attachments, $body, $file ) = (undef) x 7;

GetOptions(
    "to=s"          => \$to,
    "from=s"        => \$from,
    "subject=s"     => \$subject,
    "attachments=s" => \$attachments,
    "body=s"        => \$body,
    "file=s"        => \$file,
);
$to      = getlogin unless $to;
$from    = getlogin unless $from;
$subject = " "      unless $subject;

This wrapper up until now has worked fine when being called by other scripts. However now that we have a script being run by the Cron some funny things are happening. This Cron job calls the wrapper by only specifying -t and -su but omitting -fr (yes abbreviations of the flags are being used). The resulting email correctly sets the To: however has the Sender listed as [email protected] with the subject line blank. As per the above code I can only assume that there is something strange going between Cron and the Getopt::Long module. Does anyone know why a Cron job may cause this odd behavior? If it is something else that is wrong what would it be?

+5  A: 

Perl's getlogin probably doesn't return anything useful from cron, quoting from getlogin(3):

   getlogin() returns a pointer to a string containing
   the name of the user logged in on the controlling
   terminal of the process, or a null pointer if this
   information cannot be determined.

I suggest changing your crontab to always include the username explicitly for any options that rely on getlogin. You could also change your wrapper to use getpwuid($<). (See perlvar(1) and perlfunc(1) for details on $< and getpwuid.)

Why that screws up your mailx, I don't know, but I'm going to guess you're using backticks, exec or system with a string to start mailx, rather than exec or system with a list.

sarnold
this is my open to mailx:open( MAILX, "|$_mailx -t -r $from -s \"$subject\"" )I like the suggestions, but even if I do get a null pointer from getlogin() shouldn't the subject still be set properly?
stocherilac
perlfunc suggests the idiom: `$login = getlogin || getpwuid($<) || "Kilroy";`
mobrule
@stocherilac, your command is being run as `mailx -t -r -s <subject>`. The `-s` switch appears to be interpreted as part of an email address because it immediately follows `-r`.
sarnold
@sarnold thank you very much! Silly that I missed that.
stocherilac