Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

My sendmail stopped working in my CGI web page located on Solaris 7 web server:
open (MAIL,"| /usr/sbin/sendmail || die "$!";) print MAIL << "EOF"; To: joe@here.com From: smith@here.com Subject: data subject message body here EOF close MAIL || die "$!";
It just gives error message saying mail not working.
It works if I take out the close statement: close MAIL || die "$!";

Please advise why the close statement would make my sendmail not work?

Replies are listed 'Best First'.
Re: close statement issue
by derby (Abbot) on Mar 01, 2007 at 16:38 UTC

    open (MAIL,"| /usr/sbin/sendmail || die "$!";)
    should be
    open (MAIL,"| /usr/sbin/sendmail") || die "$!"

    -derby
Re: close statement issue
by varian (Chaplain) on Mar 01, 2007 at 17:26 UTC
    Perl variables are interpreted in here-documents. Therefore make sure your here-document data does not unintentionally contain candidates for variables, in particular '@$%' are tricky. Instead, incorporate them via literal strings:
    open (MAIL,"| /usr/sbin/sendmail || die "$!";) my $to='joe@here.com'; my $from='smith@here.com'; print MAIL << "EOF"; To: $to From: $from Subject: data subject message body here EOF close MAIL || die "$!";

      ... or, escape the sigils:

      print MAIL << "EOF"; To: joe\@here.com From: smith\@here.com ... EOF

      or, use single quotes around the EOF:

      print MAIL << 'EOF'; To: joe@here.com From: smith@here.com ... EOF
        Thanks, I tried all suggestions and it still only works if I get rid of the close statement. Any other suggestions?
Re: close statement issue
by stonecolddevin (Parson) on Mar 01, 2007 at 17:08 UTC
Re: close statement issue
by ysth (Canon) on Mar 02, 2007 at 08:25 UTC
    I too would like: to see your real code, not the mistyping of it you gave; to know what changed when it stopped working; and to know what exactly "gives error message" and what the message is. You're not giving us a lot to go on, here.

    You should include $? in your error message, like close MAIL || die "sendmail error $! status $?";.

Re: close statement issue
by ww (Archbishop) on Mar 01, 2007 at 20:24 UTC
    Methinks there's another clue in your post. If, indeed, by
    My sendmail stopped working in my CGI web page...
    you mean that it did work (as you expected) at some time in the past and no longer does so, what's changed; what's been upgraded or trashed?

    In addition, perhaps you'll tell us -- as others have at least implicityly asked -- what the actual error message is (are?).

Re: close statement issue
by Moron (Curate) on Mar 01, 2007 at 18:29 UTC
    I'm not sure if this is the main cause of the symptoms, it being that the code actually shown has some typos anyway, and might not be the "real" code (tm), but ...

    When working with pipes it is advisable to wait for the subprocess to terminate before closing the pipe (e.g. by allowing the program to exit by default in this case). Also, use "or" and "and" rather than || and && when everything to the left is a complete statement for which the or and and is to operate on the truth value, otherwise it is apt to operate on only part of the statement (an error). For example:

    use POSIX ":sys_wait_h"; my $mpid = open my $mh, "| /usr/sbin/sendmail" or die "$!"; print $mh << "EOF"; To: joe@here.com From: smith@here.com Subject: data subject message body here EOF close $mh or die "$!"; waitpid $mpid, 0;

    -M

    Free your mind

        Huh? I first discovered waitpid precisely because it doesn't, at least on SUNOS with v 5.005 and I had sysadms asking me to do something about the zombies being left in the air when I closed the pipe and returned without wait.

        -M

        Free your mind

Re: close statement issue
by Sixtease (Friar) on Mar 01, 2007 at 20:38 UTC

    Umm... I guess this couldn't be the cause because it seems to work correctly when I try it but...

    close MAIL || die "$!";

    contains the high-precedence || operator between unparenthesized operands. Perhaps your perl version is a quirky one that parses the thing incorrectly. You can't spoil anything by saying

    close(MAIL) or die "$!";

    Just my two cents.

      That is correctly parsed as close(MAIL) || die("$!"). See the precedence table in perlop; close is a "named unary operator" and has higher precedence than ||.