http://www.perlmonks.org?node_id=57258

On numerous occasions tilly has recommended File::Temp as a secure way for Perl scripts to handle temporary files.   I recently got around to following his sage advice.   Here's an elementary snippet I concocted while learning the rudiments of said CPAN module.
#!/usr/bin/perl -w # filetemptest.pl 2001-01-19 # File::Temp 0.11 File::Spec 0.82 # Perl 5.00503 Debian 2.2 "Espy" use strict; use File::Temp qw(tempfile unlink0 ); use vars qw($fh $filename); my $progname = 'filetemptest.pl'; my $template = 'filetemptestXXXXXXXXXX'; my $dir = '/tmp/'; ($fh, $filename) = tempfile($template, DIR => $dir) or die " $progname: Error creating $filename: $!"; print "\nCreated file $filename.\n"; open (TMP, "> $filename") or die "$progname: Error opening $filename for WO: $!"; print TMP "\nS'working?\n" or die "$progname: Error writing to $filename: $!"; close (TMP) or die "$progname: Error closing $filename: $!"; print "Printed data to $filename\n"; print "\nUnlinking $filename\n<ENTER> to continue, CTRL+C to abort.\n" +; my $continue = (<STDIN>); unlink0 ($fh, $filename) or die "$progname: Error unlinking file $filename safely: $!";

Replies are listed 'Best First'.
Re: scratching the surface of File::Temp
by dkubb (Deacon) on Feb 10, 2001 at 06:00 UTC

    Another great alternatives for making temporary filehandles is IO::File's new_tmpfile() method.

    I prefer to use this method when their is no need to know the name of the file. In fact, IO::File hides these implementation details from you completly, and very nicely I might add. It Does the Right Thing with respect to security, file permissions and the naming of the file to ensure there is no "filename collisions".

    Here's a quick example to illustrate how close it is compared to standard IO::File handle:

    use IO::File; my $temp_fh = IO::File->new_tmpfile or die "Could not open a temporary file: $!"; #Save some stuff in the file handle $temp_fh->print('this stuff to the file handle'); #Rewind to the beginning $temp_fh->seek(0, 0); #It can do anything that a normal IO::File file handle can while(my $line = <$temp_fh>) { print $line; #prints 'this stuff to the file handle' }

    I find temp files are really useful if you need to do alot of processing on large files/strings, and you can't do all the processing in memory.

    Here you will see a real-world example of IO::File's new_tmpfile() method in action. I wrote this example to show an interesting way to prepend any string to a filehandle.

Re: scratching the surface of File::Temp
by a (Friar) on Feb 09, 2001 at 10:33 UTC
    How come you don't use $fh? I'd've thought
    ($fh, $filename) = tempfile($template, DIR => $dir) or die " $progname: Error creating $filename: $!";
    would be mean ... ah. $fh is usable, so:
    print $fh "\nS'working?\n" or die "$progname: Error writing to $filename: $!"; close ($fh) or die "$progname: Error closing $filename: $!"; print "Printed data to $filename\n";
    works but once you close ($fh), its gone. By open(TMP, $filename .. you get a 2nd link and you can open and close TMP and still have the tmpfile $filename to work w/. On winx, I needed to $| = 1 for $fh|TMP to have any content in it (that I could see from another process), and if I *don't* close TMP the file is left around afterwards. I suppose this is what its supposed to do ... be good for semaphore files, hmm 'cept for its effort at unique file names might make expecting one difficult. The template'd work for that though.

    a

      Like you point out, a, if $fh is used instead of TMP, I lose $filehandle as soon as $fh is closed.   So how can I unlink0 with no $filehandle without generating "Use of uninitialized value @ /usr/local/lib/site_perl/File?Temp.pm line (1525|1584), <STDIN> chunk 1" ?
      #!/usr/bin/perl -w use strict; use File::Temp qw(tempfile unlink0 ); use vars qw($fh $filename); my $template = 'fileXXXXXXXXXX'; my $dir = '/tmp/'; ($fh, $filename) = tempfile($template, DIR => $dir) or die "Error creating $filename: $!"; print $fh "\nS'working?\n" or die "Error writing to $filename: $!"; close $fh or die "Error closing $filename: $!"; print "\nUnlinking $filename\n<ENTER> to continue, CTRL+C to abort.\n" +; my $continue = (<STDIN>); unlink0 ($fh, $filename) or die "Error unlinking file $filename safely: $!"
      I wouldn't be surprised if it's explained in the module's pod and I'm just not picking up on it.
          cheers,
          Don
          striving for Perl Adept
          (it's pronounced "why-bick")

      Update: Good monk a says below "not supposed to close $fh... unlink0 will handle..."
      A-ha!   that seems to do the trick. 8^)

      Update #2: But if I don't "close $fh" then "print $fh "\nS'working?\n" or die;" doesn't really happen.   So I'm still doing something wrong 8^(

        Short answer: I don't think you can. Either you're not supposed to close $fh (unlink0 will handle that) or your first method: open a 2nd link and go from there. One hopes tilly|tye|chipmunk will be along w/ the correct answer real soon now ...

        a