Как создать временный файл с определенным расширением в bash?

Я пишу оболочку script, и мне нужно создать временный файл с определенным расширением.

Я пробовал

tempname=`basename $0`
TMPPS=`mktemp /tmp/${tempname}.XXXXXX.ps` || exit 1

и

tempname=`basename $0`
TMPPS=`mktemp -t ${tempname}` || exit 1

не работает, так как первый создает имя файла с литералом "XXXXXX", а второй не дает опции для расширения.

Мне нужно расширение, чтобы превью не отказывалось открывать файл.

Изменить: Я закончил с комбинацией pid и mktemp в том, что я надеюсь, что это безопасно:

tempname=`basename $0`
TMPTMP=`mktemp -t ${tempname}` || exit 1
TMPPS="$TMPTMP.$$.ps" 
mv $TMPTMP $TMPPS || exit 1

Он уязвим для атаки на отказ в обслуживании, но я не думаю, что что-то более серьезное.

Ответ 1

Последние версии предложения mktemp --suffix:

   --suffix=SUFF
          append SUFF to TEMPLATE.  SUFF must not contain slash.  This option is implied if TEMPLATE does not end in X.

$ mktemp /tmp/banana.XXXXXXXXXXXXXXXXXXXXXXX.mp3
/tmp/banana.gZHvMJfDHc2CTilINNuq2P0.mp3

Я считаю, что для этого требуется coreutils >= 8 или около того.

Если вы создаете временный файл (более старая версия mktemp) без суффикса, и вы переименовываете его, чтобы добавить его, то, возможно, вы, вероятно, должны проверить, существует ли файл. Он не защищает вас от условий гонки, но защищает вас, если там уже есть такой файл, который был там некоторое время.

Ответ 2

Как насчет этого:

echo $(mktemp $TMPDIR/$(uuidgen).txt)

Ответ 3

MacOS Sierra 10.12 не имеет опции -suffix, поэтому я предлагаю обходное решение:

    tempname=`basename $0`
    TMPPS_PREFIX=$(mktemp "${TMPDIR:-/tmp/}${tempname}.XXXXXX")
    TMPPS=$(mktemp "${TMPPS_PREFIX}.ps")
    rm ${TMPPS_PREFIX}
    echo "Your temp file: ${TMPPS}"

Ответ 4

Вот более портативное решение (POSIX-совместимое):

temp=$(mktemp -u).ps
: >"$temp"

Первая строка запускает mktemp без создания файла, затем устанавливает temp для сгенерированного имени файла с добавлением .ps. Вторая строка затем создает его; Вместо этого можно использовать touch "$temp" если вы предпочитаете.