Secure temporary file: Difference between revisions

Content added Content deleted
No edit summary
Line 44: Line 44:
In both cases, the temporary file will be deleted automatically when the file is closed. The invisible file will not be accessible on UNIX-like systems. You can use os.link to preserve the visible temporary file contents.
In both cases, the temporary file will be deleted automatically when the file is closed. The invisible file will not be accessible on UNIX-like systems. You can use os.link to preserve the visible temporary file contents.



<pre>
>>> import tempfile
>>> import tempfile
>>> invisible = tempfile.TemporaryFile()
>>> invisible = tempfile.TemporaryFile()
>>> invisible.name
>>> invisible.name
'<fdopen>'
'<fdopen>'
>>> visible = tempfile.NamedTemporaryFile()
>>> visible = tempfile.NamedTemporaryFile()
>>> visible.name
>>> visible.name
'/tmp/tmpZNfc_s'
'/tmp/tmpZNfc_s'
>>> visible.close()
>>> visible.close()
>>> invisible.close()
>>> invisible.close()

</pre>


More low level way, if you have special needs. This was the only option before Python 2.3:
More low level way, if you have special needs. This was the only option before Python 2.3:



<pre>
fd, path = tempfile.mkstemp()
fd, path = tempfile.mkstemp()
try:
try:
# use the path or the file descriptor
# use the path or the file descriptor
finally:
finally:
os.close(fd)
os.close(fd)

</pre>

=={{header|UNIX Shell}}==

UNIX shell scripts cannot guarantee secure, race-free, exclusive access to an open file descriptor.
The best approach to working around this limitation is to create a directory (the ''mkdir'' command
is a wrapper around the atomic ''mkdir()'' system call) and then perform all temporary file operations
thereunder.

RESTOREUMASK=$(umask)
TRY=0
while :; do
let TRY+=1 ## No spaces around += operator in let statement!
umask 0077
MYTMP=${TMPDIR:-/tmp}/$(basename $0).$$.$(date +%s).$TRY
trap "rm -fr $MYTMP" EXIT
mkdir "$MYTMP" 2>/dev/null && break
done
umask "$RESTOREUMASK"
cd ""$MYTMP" || {
echo "Temporary directory failure on $MYTMP" >&2
exit 1; }

Note that the shell special variable $$ (the PID of the currently ''exec()''-ed shell) is unique at any given
moment on a UNIX system, and $(date +%s) gives the time represented as a number of seconds since the UNIX epoch
(GNU date or any other with the %s extension). So any name collision here is most likely "enemy action."
This code will loop, picking new names and resetting the ''trap'' (clean-up command) until it succeeds in making
a directory. (Simple changes to the code could limit the number of attempts or implement a timeout).