jan*_*nos 57 directory shell-script tmp
I have a script that needs to create temporary files for its work, and clean up after itself. My question is about finding the right base directory for the temporary files.
The script needs to work on multiple platforms: Git Bash (Windows), Solaris, Linux, OSX. On each platform, the preferred temp directory is expressed differently:
%TMP%
(and possibly %TEMP%
)$TMPDIR
$TMPDIR
but appears to be unset on multiple systems I triedSo in my script I added this boilerplate:
if test -d "$TMPDIR"; then
:
elif test -d "$TMP"; then
TMPDIR=$TMP
elif test -d /var/tmp; then
TMPDIR=/var/tmp
else
TMPDIR=/tmp
fi
Run Code Online (Sandbox Code Playgroud)
This seems too tedious. Is there a better way?
Joh*_*ith 87
A slightly more portable way to handle temporary files is to use mktemp
. It'll create temporary files and return their paths for you. For instance:
$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P
Run Code Online (Sandbox Code Playgroud)
You could use it in a script quite easily:
tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile
Run Code Online (Sandbox Code Playgroud)
Reading the man page, you should be able to set options according to your needs. For instance:
-d
creates a directory instead of a file.-u
generates a name, but does not create anything.Using -u
you could retrieve the temporary directory quite easily with...
$ tmpdir=$(dirname $(mktemp -u))
Run Code Online (Sandbox Code Playgroud)
More information about mktemp
is available here.
Edit regarding Mac OS X: I have never used a Mac OSX system, but according to a comment by Tyilo below, it seems like Mac OSX's mktemp
requires you to provide a template (which is an optional argument on Linux). Quoting:
The template may be any file name with some number of "Xs" appended to it, for example
/tmp/temp.XXXX
. The trailing "Xs" are replaced with the current process number and/or a unique letter combination. The number of unique file names mktemp can return depends on the number of "Xs" provided; six "Xs" will result in mktemp selecting 1 of 56800235584 (62 ** 6) possible file names.
The man page also says that this implementation is inspired by the OpenBSD man page for mktemp
. A similar divergence might therefore be observed by OpenBSD and FreeBSD users as well (see the History section).
现在,您可能已经注意到,这需要您指定一个完整的文件路径,包括您在问题中查找的临时目录。这个小问题可以使用-t
开关来处理。虽然这个选项似乎需要一个参数 ( prefix
),但它似乎在必要时mktemp
依赖$TMPDIR
。
总而言之,您应该能够获得与上述相同的结果...
$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))
Run Code Online (Sandbox Code Playgroud)
非常感谢 Mac OS X 用户的任何反馈,因为我无法自己测试此解决方案。
fro*_*utz 10
如果您在更少的行中寻找相同的东西......
for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
test -d "$TMPDIR" && break
done
Run Code Online (Sandbox Code Playgroud)
你可以把这个写成一个。
你可能会这样做:
: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit
Run Code Online (Sandbox Code Playgroud)
shell 应该在 4 个备选方案之一中找到一个可执行目录,或者以有意义的错误退出。尽管如此,POSIX 定义了$TMPDIR
变量(对于 XCU 系统):
TMPDIR
此变量应代表一个目录的路径名,该目录可供需要一个位置来创建临时文件的程序使用。
它还需要/tmp
路径。