How can I generate random unique temp file names?

10,866

Solution 1

If you don't create the file at the same time you create the name then it is possible for the a file with the same name to be created before you create the file manually. If you need to have a different process open the file, simply close it first:

#!/usr/bin/perl

use strict;
use warnings;

use File::Temp;

sub get_temp_filename {
    my $fh = File::Temp->new(
        TEMPLATE => 'tempXXXXX',
        DIR      => 'mydir',
        SUFFIX   => '.dat',
    );

    return $fh->filename;
}

my $filename = get_temp_filename();

open my $fh, ">", $filename
    or die "could not open $filename: $!";

The best way to handle the permissions problem is to make sure the users that run the two programs are both in the same group. You can then use chmod to change the permissions inside the first program to allow the second program (or any user in that group) to modify the file:

my $filename = get_temp_filename();

chmod 0660, $filename;

Solution 2

Just to obtain the name of the tempfile you can do:

#!/usr/bin/perl
use strict;
use warnings;
use 5.10.1;

use File::Temp qw/tempfile/;

my $file;

(undef, $file) = tempfile('tmpXXXXXX', OPEN=>0);

say $file;

But as Chas. Owens said, be careful the same name could be created before you use it.

Solution 3

The get_temp_filename function proposed by Chas. Owens uses a local filehandle object ($fh), which is destroyed upon function return, leading to the created tempfile destruction.

To avoid this, and therefore keep the file (less risk) add:

UNLINK => 0

to the new method arguments, forbidding file unlink at object deletion time.

Solution 4

Actually, I agree with Chas.Owens - the design is fatally flawed.

It really feels like you need to fix the design, so:

If you have control of the 2nd program, have that program create the filename and the file, and pass the filename to the 1st program.


But, if the 2nd program isn't something you wrote and so you cannot modify it then I'd recommend one of the following:

1 - Use the first processes PID as part of the file name in an attempt to minimize the risks of duplicate filenames.

2 - Have the 2nd program pipe its output to the 1st program, don't bother with a file at all. Personally, this is a much better solution than 1.

3 - Wrap the 2nd program in a script (shell, perl, whatever) which creates the name and the file and passes that to both programs.

Share:
10,866
Tree
Author by

Tree

Updated on June 25, 2022

Comments

  • Tree
    Tree almost 2 years

    I am trying to create a temp file using the following code:

     use File::Temp  ;
     $tmp = File::Temp->new( TEMPLATE => 'tempXXXXX',
                            DIR => 'mydir',
                            SUFFIX => '.dat');
    

    This is create the temp file. Because of my permission issue, the other program is not able to write into file.

    So I just want to generate the file name without creating the file. Is there any where to do that?

  • Philippe A.
    Philippe A. over 11 years
    Natmaka's comment below is right, in that the file will be deleted when the function returns. For my own need, I am keeping unlink set and I return the filehandle. I am free to close file or not depending on the situation. The file still is deleted when the program exits.