version 1.33, 2024/03/01 23:37:42 |
version 1.34, 2024/03/03 15:24:45 |
|
|
.Os |
.Os |
.Sh NAME |
.Sh NAME |
.Nm mktemp |
.Nm mktemp |
.Nd make temporary filename (unique) |
.Nd make temporary file or directory (unique) |
.Sh SYNOPSIS |
.Sh SYNOPSIS |
.Nm mktemp |
.Nm mktemp |
.Op Fl dqtu |
.Op Fl dqtu |
|
|
.Sh DESCRIPTION |
.Sh DESCRIPTION |
The |
The |
.Nm mktemp |
.Nm mktemp |
utility takes the given filename |
utility takes the specified file name |
.Ar template |
.Ar template |
and overwrites a portion of it to create a unique filename. |
and overwrites a portion of it to create a unique file name. |
The |
The |
.Ar template |
.Ar template |
may be any filename with at least six |
may be any file name containing at least six |
.Ql X Ns s |
.Ql X Ns s |
in the last component of the filename, for example |
in the last component of the path, for example |
.Pa /tmp/tfile.XXXXXXXXXX |
.Pa /tmp/tfile.XXXXXXXXXX |
or |
or |
.Pa /tmp/editor.XXXXXXXXXX.txt . |
.Pa /tmp/editor.XXXXXXXXXX.txt . |
|
|
only the last one will be considered. |
only the last one will be considered. |
If no |
If no |
.Ar template |
.Ar template |
is specified, a default of |
is specified, a default value of |
.Pa tmp.XXXXXXXXXX |
.Pa tmp.XXXXXXXXXX |
is used and the |
is used and the |
.Fl t |
.Fl t |
|
|
.Ql X Ns s |
.Ql X Ns s |
in the |
in the |
.Ar template |
.Ar template |
and the number of collisions with pre-existing files. |
and the number of collisions with pre-existing entries. |
The number of unique filenames |
The number of unique names |
.Nm |
.Nm |
can return depends on the number of |
can return depends on the number of |
.Ql X Ns s |
.Ql X Ns s |
|
|
.Pp |
.Pp |
If |
If |
.Nm |
.Nm |
can successfully generate a unique filename, the file (or directory) |
successfully generates a unique name, the file (or directory) |
is created with file permissions such that it is only readable and writable |
is created with permissions such that it is only readable and writable |
by its owner (unless the |
by its owner (unless the |
.Fl u |
.Fl u |
flag is given) and the filename is printed to standard output. |
flag is given) and the name is printed to the standard output. |
.Pp |
.Pp |
.Nm mktemp |
.Nm mktemp |
is provided to allow shell scripts to safely use temporary files. |
is provided to allow shell scripts to safely use temporary files. |
Traditionally, many shell scripts take the name of the program with |
Traditionally, many shell scripts take the name of the program with |
the PID as a suffix and use that as a temporary filename. |
the PID as a suffix and use that as a temporary file name. |
This kind of naming scheme is predictable and the race condition it creates |
This kind of naming scheme is predictable and the race condition it creates |
is easy for an attacker to win. |
is easy for an attacker to win. |
A safer, though still inferior approach |
A safer, though still inferior approach, |
is to make a temporary directory using the same naming scheme. |
is to make a temporary directory using the same naming scheme. |
While this does allow one to guarantee that a temporary file will not be |
While this does allow one to guarantee that a temporary file will not be |
subverted, it still allows a simple denial of service attack. |
subverted, it still allows a simple denial of service attack. |
|
|
.It Fl p Ar directory |
.It Fl p Ar directory |
Use the specified |
Use the specified |
.Ar directory |
.Ar directory |
as a prefix when generating the temporary filename. |
as a prefix when generating the temporary name. |
The |
The |
.Ar directory |
.Ar directory |
will be overridden by the user's |
will be overridden by the user's |
|
|
fragment illustrates a simple use of |
fragment illustrates a simple use of |
.Nm |
.Nm |
where the script should quit if it cannot get a safe |
where the script should quit if it cannot get a safe |
temporary file. |
temporary file: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1 |
TMPFILE=`mktemp /tmp/example.XXXXXXXXXX` || exit 1 |
echo "program output" >> $TMPFILE |
echo "program output" >> $TMPFILE |
|
|
.Pp |
.Pp |
The same fragment with support for a user's |
The same fragment with support for a user's |
.Ev TMPDIR |
.Ev TMPDIR |
environment variable can be written as follows. |
environment variable can be written as follows: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMPFILE=`mktemp -t example.XXXXXXXXXX` || exit 1 |
TMPFILE=`mktemp -t example.XXXXXXXXXX` || exit 1 |
echo "program output" >> $TMPFILE |
echo "program output" >> $TMPFILE |
|
|
the temporary file. |
the temporary file. |
In this case the |
In this case the |
.Fl t |
.Fl t |
flag is implied. |
flag is implied: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMPFILE=`mktemp` || exit 1 |
TMPFILE=`mktemp` || exit 1 |
echo "program output" >> $TMPFILE |
echo "program output" >> $TMPFILE |
|
|
.Pa /extra/tmp |
.Pa /extra/tmp |
unless the user's |
unless the user's |
.Ev TMPDIR |
.Ev TMPDIR |
environment variable specifies otherwise. |
environment variable specifies otherwise: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMPFILE=`mktemp -p /extra/tmp example.XXXXXXXXXX` || exit 1 |
TMPFILE=`mktemp -p /extra/tmp example.XXXXXXXXXX` || exit 1 |
echo "program output" >> $TMPFILE |
echo "program output" >> $TMPFILE |
|
|
.Pp |
.Pp |
In other cases, we want the script to catch the error. |
In other cases, we want the script to catch the error. |
For instance, if we attempt to create two temporary files and |
For instance, if we attempt to create two temporary files and |
the second one fails we need to remove the first before exiting. |
the second one fails we need to remove the first before exiting: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMP1=`mktemp -t example.1.XXXXXXXXXX` || exit 1 |
TMP1=`mktemp -t example.XXXXXXXXXX.1` || exit 1 |
TMP2=`mktemp -t example.2.XXXXXXXXXX` |
TMP2=`mktemp -t example.XXXXXXXXXX.2` |
if [ $? -ne 0 ]; then |
if [ $? -ne 0 ]; then |
rm -f $TMP1 |
rm -f $TMP1 |
exit 1 |
exit 1 |
|
|
Or perhaps you don't want to exit if |
Or perhaps you don't want to exit if |
.Nm |
.Nm |
is unable to create the file. |
is unable to create the file. |
In this case you can protect that part of the script thusly. |
In this case you can protect that part of the script thusly: |
.Bd -literal -offset indent |
.Bd -literal -offset indent |
TMPFILE=`mktemp -q -t example.XXXXXXXXXX` && { |
TMPFILE=`mktemp -q -t example.XXXXXXXXXX` && { |
# Safe to use $TMPFILE in this block |
# Safe to use $TMPFILE in this block |