tags:

views:

117

answers:

4

I'm trying to copy some files from one network share to another using File::Copy.

This is my code

 #!C:/strawberry/perl/bin/perl.exe
 use File::Copy;
 print "Content-type: text/html\n\n";
 print "<H1>Hello World</H1>\n";
 copy("s:\\nl\\cover\\config.jsp", "s:\\temp\\config.jsp") 
     or die "File cannot be copied.";
 print "this is not displayed";

Why is my 'die'-message not being displayed?

+4  A: 

Are you sending your stderr to the stdout stream as well? All your prints will got to stdout which is presumably connected to a browser, given your HTML output.

However, die writes to the stderr stream. This is likely to go, not to the browser window, but to an error log of some sort. As to where it's going, it depends on what Perl is running within.

One way to check is to print something instead of dieing in the or clause.

So, some questions:

  1. How are you running it?
  2. If on the command line, show us the exact command.
  3. If in a web server of some sort, tell us which one so we can find the logs for you.
paxdiablo
how do i do this ?
xyleen
copy("s:\\nl\\cover\\config.jsp", "s:\\temp\\config.jsp") or print "Aarrgghh!";
paxdiablo
die does more than just print a message. It will also exit the script, and perhaps other things. (Return an error code?)
Ryan Fox
Try using `use CGI::Carp qw(fatalsToBrowser);` if only for testing purposes
bart
@Ryan, I wasn't proposing print as a solution, just as a means to find out if my stdout/stderr hypothesis was correct.
paxdiablo
+4  A: 

If you are running this under a web server (I cannot imagine why, you are sending a "Content-Type" header), any error messages you emit using die and warn will go to the server's error log.

Further, if you are invoking this as CGI, note that you are lying to the browser by claiming you are sending HTML and not sending HTML.

Especially if you are just learning Perl, you should make an effort to dot all your is and cross all your ts:

#!C:/strawberry/perl/bin/perl.exe

use strict;   # every time
use warnings; # every time

use CGI qw(:cgi);
use CGI::Carp qw(fatalsToBrowser); # only during debugging

use File::Copy;
use File::Spec::Functions qw(catfile);

$| = 1;

# prefer portable ways of dealing with filenames
# see http://search.cpan.org/perldoc/File::Spec

my $source = catfile(qw(S: n1 cover config.jsp));
my $target = catfile(qw(S: temp config.jsp));

print header('text/plain');

if ( copy $source => $target ) {
    print "'$source' was copied to '$target'\n";
}
else {
    print "'$source' was not copied to '$target'\n";
    # you can use die if you want the error message to
    # go to the error log and an "Internal Server Error"
    # to be shown to the web site visitor.
    # die "'$source' was not copied to '$target'\n";
}

See CGI for the function oriented interface import lists.

Sinan Ünür
Probably also a good idea to add use Carp qw(fatalsToBrowser); so that messages are sent to the browser.
squeeks
thanks sinan, i've tried your code but it gives me an 'internal error'
xyleen
@xyleen my `use CGI` line was wrong.
Sinan Ünür
@sinan : Premature end of script headers: pub2.pl
xyleen
A: 
copy("s:\\nl\\cover\\config.jsp", "s:\\temp\\config.jsp") 
     or die "File cannot be copied.";
print "this is not displayed";

Only one of these messages should ever be displayed and it's unclear which you're asking about.

The question says you're wondering why the die message isn't being displayed; to me, that implies that you're not seeing the message "File cannot be copied." and the most obvious reason for this is that the copy operation is succeeding, but see also the previous responses about looking in the error log if you're running this under CGI.

The text of the messages, though, suggests that you actually mean you're not seeing the message "this is not displayed". (Why else would you mention that it isn't displayed?) In that case, the reason you're not seeing it is because die causes the program to exit. After the copy fails and the die executes, your program is dead. Terminated. It has shuffled off this mortal CPU and joined the stack eternal. It wouldn't print "this is not displayed" if you put four million volts through it. It is an ex-process.

Dave Sherohman
+2  A: 

die sends messages to STDERR, which will wind up in the web server's error logs, not on the screen. There are some CGI modules that offer you greater control over error-handling, or you could install a $SIG{__DIE__} handler (if you don't know what that is, then don't worry -- you don't need to), but when I want a quick-and-dirty way to debug my CGI scripts, I put this at the top of the script:

    #! /usr/bin/perl
    $src = join'',<DATA>;
    eval $src;
    print "Content-type: text/plain\n\n$@\n" if $@;
    __END__
    ... my cgi script starts here ...

This loads the script into a variable, uses eval to run the Perl interpreter on that variable's contents, and prints any errors to standard output (the browser window) with a valid header.

mobrule