Re: Safe Temp Files
by xdg (Monsignor) on Dec 04, 2006 at 16:10 UTC
|
That use of open is only available since 5.8. (See perl58delta.) That may or may not be important to you.
File::Temp can also be helpful if you need the filename or need the file to persist beyond one open/close cycle, but still be cleaned up later. (Both of which are less "safe" depending on how you're using it.)
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
| [reply] [d/l] |
Re: Safe Temp Files
by blue_cowdawg (Monsignor) on Dec 04, 2006 at 16:41 UTC
|
Is there any reason to believe that one method is more safe and/or reliable than the other?
While "safe" might be in the eye of the beholder (and I know I'm going to draw comments on that statement) reliable is another matter.
First off, I try and write my code in such a way that I don't need temporary files. Leaving surds all over the disk is somthing I don't like to do and I'll go to great lengths to avoid it. My biggest issue with temporary files is they
tend to become "permanent" files because quite
often either because of oversight on the behalf of the programmer or because Something Bad Happened™ to the
process during its lifecycle the temporary files don't
get cleaned up after.
Having asserted that premise I'll go on to say that in the rare occasion that I need a temporary file I tend to use one of two methods.
Name it by PID
The most common way I enact a temporary file is to create a filename that is related to both the reason I'm creating
it and the process id for example:
my $unsortedUsersFilename="munger-unsortedusers.$$.txt";
|
etc
In this example, munger is the name of the
script doing the work, unsertedusers refers
to the fact that it will contain a set of unsorted users
(hey! work with me here!) and the $$ is the
*nix PID of the script that is creating it.
During debugging sessions I may well leave off the step
of removing the temp file so I can examine this file and
know what was going on if the code doesn't work the way
I expected it to.
The don't reinvent the wheel method
I like using File::Temp once my script has been
debugged and I no longer care about the name of the being
generated. While the module does provide a templating
function for filenames, the names are still random.
The biggest reason I like this module is it is platform
portable. While 99.999% of my scripting is done on the
*nix family of OSs every once in a while I end up writing
something on the Evil Empire®
platform and so I like things that I write to be portable.
Hope this at least provides you with food for thought.
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] [d/l] [select] |
|
|
Using a PID is easy and commonly used on UNIX, but it might bite you if you port that to Windows if you want the file to survive after the program. On UNIX the PIDs cycle around, and it will be "a long time" before your PID gets reused, but on Windows a PID can get reused by the next process that starts.
| [reply] |
|
|
| [reply] |
Re: Safe Temp Files
by fmerges (Chaplain) on Dec 04, 2006 at 16:13 UTC
|
Hi,
I would use File::Temp, its compatible with older version of Perl, and is less obscure than this special open call syntax.
Regards,
fmerges at irc.freenode.net
| [reply] |
Re: Safe Temp Files
by blazar (Canon) on Dec 04, 2006 at 16:24 UTC
|
open($fh, "+>", undef) or die ...
I love that! But one thing that hasn't been mentioned yet, and that may be relevant or not to you is that it opens a handle to an anonymous file. (On filesystems that do support them.)
| [reply] [d/l] |
Re: Safe Temp Files
by ambrus (Abbot) on Dec 04, 2006 at 17:09 UTC
|
The advantage of File::Temp is that you can use it if you need the name of the temp file. The advantage of open is that its syntax is simpler.
| [reply] |
|
|
open(my $fh, "+>", undef) or die ...
use File::Temp ();
my $fh = File::Temp->new or die ...
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
| [reply] [d/l] [select] |
|
|
my $fh = File::Temp->new
is always enough to make me go "WTF...?".
I wish the module author had put some more inspiration in the name for the constructor, like Tim Bunce used "connect" in DBI instead of the plain, boring and somewhat obscure "new". I like this a lot better. | [reply] [d/l] |
|
|
Re: Safe Temp Files
by gmock (Acolyte) on Dec 05, 2006 at 14:57 UTC
|
Thank you all for your kind replies. But I don't see where my basic question was answered.
Which method is safer and/or more reliable? I think they are about the same. Am I correct?
Thanks!
-George | [reply] |
|
|
I would recommend using File::Temp. I think it is equally safe/reliable, gives more portability (to older Perls), and gives more flexibility.
For example, if you want your temporary files to stick around for inspection during debugging, you can just tell File::Temp not to unlink them on exit if debugging is on.
use constant DEBUG => 1;
my $fh = File::Temp->new( UNLINK => DEBUG ? 0 : 1 );
If you're in the habit of using File::Temp, you'll always have the full flexibility it gives available to you.
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
| [reply] [d/l] |
|
|
Can you be more specific about what safe and reliable mean to you? For instance is saftey a matter of hacker-proofing, like the way CGI unlinks it's file handles to avoid spying by others? Is reliability a matter of portability from one OS to another or is it about always getting a unique filename in each situation? Clarifying these might lead to more specific opinions.
| [reply] |
Re: Safe Temp Files
by Cabrion (Friar) on Dec 05, 2006 at 12:50 UTC
|
You might check out how the CGI module implements temp-files. It takes things a step further and unlinks the file after an open() wich makes it harder for another process to intercept the file handle. | [reply] |
|
|
stout:~ [16:28:32]$ strace -eopen,unlink perl -e 'open $f, "+>", undef
+'
open("/etc/ld.so.preload", O_RDONLY) = 3
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/libpthread.so.0", O_RDONLY) = 3
open("/lib/libnsl.so.1", O_RDONLY) = 3
open("/lib/libdl.so.2", O_RDONLY) = 3
open("/lib/libm.so.6", O_RDONLY) = 3
open("/lib/libcrypt.so.1", O_RDONLY) = 3
open("/lib/libutil.so.1", O_RDONLY) = 3
open("/lib/libc.so.6", O_RDONLY) = 3
open("/dev/urandom", O_RDONLY|O_LARGEFILE) = 3
open("/dev/null", O_RDONLY|O_LARGEFILE) = 3
open("/tmp/PerlIO_dr5fu4", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) =
+3
unlink("/tmp/PerlIO_dr5fu4") = 0
Process 17389 detached
Also see:
stout:~ [16:29:17]$ perl -le 'open $f, "+>", undef; system "ls -l /pro
+c/$$/fd"'
total 5
lrwx------ 1 blazar users 64 Dec 6 16:29 0 -> /dev/pts/0
lrwx------ 1 blazar users 64 Dec 6 16:29 1 -> /dev/pts/0
lrwx------ 1 blazar users 64 Dec 6 16:29 2 -> /dev/pts/0
lrwx------ 1 blazar users 64 Dec 6 16:29 3 -> /tmp/.nfs00364089000002
+21
lr-x------ 1 blazar users 64 Dec 6 16:29 4 -> pipe:[12410097]
(That's because /tmp is nfs mounted here, under other fs's it would explicitly tell you it has been deleted - at least IIRC it did when I tried it.) | [reply] [d/l] [select] |