Secure temporary file: Difference between revisions
Content added Content deleted
m (→{{header|D}}: typos) |
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). |