Как я могу создать временный файл с определенным расширением в Bash?
Я пишу сценарий оболочки, и мне нужно создать временный файл с определенным расширением.
я пробовал
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
Он уязвим для атаки типа "отказ в обслуживании", но я не думаю, что что-то более серьезное.
8 ответов
Последние версии 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) без суффикса и переименовываете его, чтобы добавить один, наименее вероятно, что вы могли бы сделать, это проверить, существует ли файл уже. Он не защищает вас от условий гонки, но защищает, если уже есть такой файл, который был там некоторое время.
Все эти решения, кроме --suffix (который не всегда доступен), имеют состояние гонки. Вы можете устранить состояние гонки, используя mktemp -d для создания каталога, а затем поместив туда свой файл.
mydir=`mktemp -d`
touch "$mydir"/myfile.ps
Вот более портативное решение (совместимое с POSIX):
temp=$(mktemp -u).ps
: >"$temp"
Первая строка проходит mktemp
без создания файла, затем устанавливает temp
к сгенерированному имени файла с .ps
добавлено. Вторая строка затем создает его;touch "$temp"
можно использовать вместо этого, если вы предпочитаете это.
РЕДАКТИРОВАТЬ: обратите внимание, что у этого нет тех же разрешений, которые он создает с помощью перенаправления оболочки. Если вам нужно, чтобы его не могли прочитать другие пользователи, вы можете использоватьchmod
установить его вручную.
MacOS Ventura 13.1 по-прежнему не поддерживает--suffix
. Но, основываясь на ответе Романа Чернятчика, я использую встроенное решение, которое я считаю самым простым:
mktemp "$(mktemp -t $tempname).ps"
В 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}"
В macOS 13,mktemp
все еще не поддерживает--suffix
, я переименовываю его после создания файла, кажется, он работает нормально.
$ tmp=`mktemp -t prefix`
$ mv $tmp $tmp.txt
$ ls $tmp.txt
/var/folders/..../T/prefix.xxxx.txt
Для macOS -
brew install coreutils
Потом -
gmktemp --suffix=.ps