在多个平台上找到正确的tmp目录


46

我有一个脚本,需要为其工作创建临时文件,然后自行清理。我的问题是关于为临时文件找到正确的基本目录。

该脚本需要在多个平台上工作:Git Bash(Windows),Solaris,Linux,OSX。在每个平台上,首选的temp目录均以不同的方式表示:

  • Windows :(%TMP%可能还有%TEMP%
  • OSX: $TMPDIR
  • Linux,UNIX:应该是,$TMPDIR但在我尝试的多个系统上似乎未设置

因此,在我的脚本中,我添加了以下样板:

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

这似乎太乏味了。有没有更好的办法?


6
只需${TMPDIR-/tmp}在类Unix上使用即可。TMPDIR(由系统,管理员或用户)在那里告诉您什么时候不使用/tmp临时文件。
斯特凡Chazelas

Answers:


72

处理临时文件的一种更便携式的方法是使用mktemp。它将创建临时文件并为您返回它们的路径。例如:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

您可以很容易地在脚本中使用它:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

阅读手册页,您应该能够根据需要设置选项。例如:

  • -d 创建目录而不是文件。
  • -u 生成一个名称,但不创建任何内容。

使用... -u可以很容易地检索临时目录。

$ tmpdir=$(dirname $(mktemp -u))

有关更多信息,mktemp请参见此处

关于Mac OS X的编辑:我从未使用过Mac OSX系统,但是根据下面Tyilo的评论,看来Mac OSX mktemp要求您提供模板(这是Linux上的可选参数)。报价:

模板可以是任何文件名,例如,后接一些“ X” /tmp/temp.XXXX。尾随的“ X”将替换为当前的过程编号和/或唯一的字母组合。mktemp可以返回的唯一文件名的数量取决于所提供的“ Xs”的数量。六个“ X”将导致mktemp选择56800235584(62 ** 6)可能的文件名中的1个。

手册页还说此实现是受OpenBSD手册页的启发mktemp。因此,OpenBSD和FreeBSD用户也可能会观察到类似的差异(请参阅“ 历史记录”部分)。

现在,您可能已经注意到,这需要您指定完整的文件路径,包括您要在问题中查找的临时目录。使用-t开关可以解决这个小问题。尽管此选项似乎需要一个参数(prefix),但它似乎在必要时mktemp依赖$TMPDIR

总而言之,使用...您应该能够获得与上述相同的结果。

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Mac OS X用户的任何反馈将不胜感激,因为我无法自己测试此解决方案。


OP在现在已删除的评论中解决了这个问题;恐怕我无法为需要gitbash外壳程序接口的系统提供答案,因此我“有点”。我实际上无法告诉您临时文件在Windows系统上的存储位置...
John WH Smith

1
同上。有些疯狂c:\User\Name\..............\stuff。而且大概有一百个。尽管如此,一些Linux发行版仍在接近疯狂程度/var。我只是好奇而已。令我感到惊讶的是,一切都变得奇怪了-根据我的经验,挫折感非常容易携带,而便利性则更是如此。无论如何,很好的答案。
mikeserv

1
大约一年前,我写了一个Bash脚本来处理在Win2K到WinXP上都可以使用的Windows Restore Point文件(以后的版本以不同的方式处理这些东西)。我的脚本使用WINDOWS/TempWindows/Temp作为其临时文件的默认目录;该目录在Windows 7计算机上也存在。但是我的脚本允许用户在命令行上提供备用的temp目录。
下午14年

这在OS X上不起作用,因为您必须为提供模板mktemp
蒂洛2014年

1
从El Capitan开始,mktemp它就可以工作:simple mktemp返回一个文件,并mktemp -d返回一个目录;无需模板。该手册是不是虽然更新。
富兰克林·于

9

如果您正在寻找更少的行中的同一件事...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

您可以合而为一。


您可能还应该测试它是否可写。
弗罗斯特斯2014年

@janos:如果其他所有方法均失败,请要求用户提供临时文件的路径,或允许它们在命令行上指定一个。
2

6

您可以这样做:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

外壳程序应该在4个替代方法之一中找到可执行目录,或者退出并显示有意义的错误。POSIX仍然定义了$TMPDIR变量(用于XCU系统)

TMPDIR 该变量应表示目录的路径名,该目录可用于需要放置临时文件的地方的程序。

它还需要/tmp路径。


1
这是IMO唯一的正确答案。邓诺(Dunno)坐在无声无息的情况下正在做什么……
Graeme 2014年

2
@Graeme:也许是因为它根本不可读?
ssc 2016年

我投票赞成,但随后撤回了它-是的,这个答案是一团糟,似乎在一个有用的轨道上,但是根本不清楚代码片段正在尝试执行的操作-第一行是注释,第二行是注释一个是错误(无论如何,都是bash)。可以使用一些工作。
唐·哈奇

哦,我知道,答案的第一个版本更加清晰(尽管您实际上尝试运行它,但在第二行还是有一个错误)...然后进行了一系列编辑,完全破坏了代码示例,因此现在变得毫无意义。可以使用另外一两个通行证:-)
唐·哈奇
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.