如何创建临时目录?

我用来创建一个tempfile,删除它并将其重新创建为一个目录:

temp=`tempfile`
rm -f $temp
# <breakpoint>
mkdir $temp

问题是,当它运行到& lt; breakpoint>时,恰好有另一个程序想要做同样的事情,而mkdir-ed一个具有相同名称的临时目录,将导致该程序失败。

192338 次浏览

使用mktemp -d。它创建一个随机名称的临时目录,并确保该文件不存在。不过,您需要记得在使用该目录后删除它。

我最喜欢的一句话是

cd $(mktemp -d)

对于一个更健壮的解决方案,我使用类似下面的东西。这样,临时目录将在脚本退出后始终被删除。

清理函数在EXIT信号上执行。这保证了清除函数总是被调用,即使脚本在某处中止。

#!/bin/bash


# the directory of the script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"


# the temp directory used, within $DIR
# omit the -p parameter to create a temporal directory in the default location
WORK_DIR=`mktemp -d -p "$DIR"`


# check if tmp dir was created
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
echo "Could not create temp dir"
exit 1
fi


# deletes the temp directory
function cleanup {
rm -rf "$WORK_DIR"
echo "Deleted temp working directory $WORK_DIR"
}


# register the cleanup function to be called on the EXIT signal
trap cleanup EXIT


# implementation of script starts here
...

在这里中的bash脚本目录。

Bash 陷阱

下面的代码片段将安全地创建并清理一个临时目录。

当接收到任何指定的信号时,第trap行执行exit 1命令。第二行trap删除程序退出时的$TEMPD(正常和异常)。我们在检查mkdir -d成功后初始化这些陷阱,以避免意外地在$TEMPD处于未知状态时执行退出陷阱。

#!/bin/bash


# set -x # un-comment to see what's going on when you run the script


# Create a temporary directory and store its name in a variable.
TEMPD=$(mktemp -d)


# Exit if the temp directory wasn't created successfully.
if [ ! -e "$TEMPD" ]; then
>&2 echo "Failed to create temp directory"
exit 1
fi


# Make sure the temp directory gets removed on script exit.
trap "exit 1"           HUP INT PIPE QUIT TERM
trap 'rm -rf "$TEMPD"'  EXIT

下面是关于如何使用模板创建临时目录的简单解释。

  1. 安全地创建一个临时文件或目录,并打印其名称。
  2. TEMPLATE在最后一个组件中必须包含至少3个连续的'X'。
  3. 如果没有指定TEMPLATE,它将使用tmp。XXXXXXXXXX
  4. 创建的目录为u+rwx,减去umask限制。

PARENT_DIR=./temp_dirs # (optional) specify a dir for your tempdirs
mkdir $PARENT_DIR


TEMPLATE_PREFIX='tmp' # prefix of your new tempdir template
TEMPLATE_RANDOM='XXXX' # Increase the Xs for more random characters
TEMPLATE=${PARENT_DIR}/${TEMPLATE_PREFIX}.${TEMPLATE_RANDOM}


# create the tempdir using your custom $TEMPLATE, which may include
# a path such as a parent dir, and assign the new path to a var
NEW_TEMP_DIR_PATH=$(mktemp -d $TEMPLATE)
echo $NEW_TEMP_DIR_PATH


# create the tempdir in parent dir, using default template
# 'tmp.XXXXXXXXXX' and assign the new path to a var
NEW_TEMP_DIR_PATH=$(mktemp -p $PARENT_DIR)
echo $NEW_TEMP_DIR_PATH


# create a tempdir in your systems default tmp path e.g. /tmp
# using the default template 'tmp.XXXXXXXXXX' and assign path to var
NEW_TEMP_DIR_PATH=$(mktemp -d)
echo $NEW_TEMP_DIR_PATH


# Do whatever you want with your generated temp dir and var holding its path


在macOS上的bash脚本中,我在命名空间目录中创建临时文件,并尝试每次重用它:


$ namespace="com.namespace.mktemp"


# find directory for reusing
$ ls -d "${TMPDIR}${namespace}"*


# create directory if not exists
$ mktemp -d -t "$namespace"
/var/folders/s_/.../T/com.namespace.mktemp.HjqGT6w2


# create tempfile with directory name and file prefix
$ mktemp -t "com.namespace.mktemp.HjqGT6w2/file-prefix"
/var/folders/s_/.../T/com.namespace.mktemp.HjqGT6w2/file-prefix.sZDvjo14


# add suffix - `mktemp` on macOS does not support `--suffix`
mv "$tempfile" "$tempfile.txt"


gmktemp (brew install coreutils)有点不同:

  • 支持--suffix--tmpdir
  • templateprefix中需要x
  • template不应包含目录,应改为设置TMPDIR

$ namespace="com.namespace.gmktemp"


# create directory if not exists
$ gmktemp -d -t "$namespace.XXXXXXXX"
/var/folders/s_/.../T/com.namespace.gmktemp.BjFtIAyZ


# set TMPDIR
TMPDIR="/var/folders/s_/.../T/com.namespace.gmktemp.BjFtIAyZ"


# create tempfile with directory name and file prefix
$ gmktemp --suffix=".txt" -t "prefix.XXXXXXXX"
/var/folders/s_/.../T/com.namespace.gmktemp.BjFtIAyZ/prefix.LWHj0G95.txt