Geçici bir dizin nasıl oluşturulur?


229

Bir oluşturmak tempfile, silmek ve bir dizin olarak yeniden oluşturmak için kullanın :

tmpnam=`tempfile`
rm -f $tmpnam
mkdir "$tmpnam"

Sorun, Xyanlışlıkla bir işlemden sonra rm -f Xve hemen önce geçici dosya yürütürse , başka bir işlem aynı adı alabilir mkdir X.

Yanıtlar:


341

Kullanın mktemp -d. Rastgele bir adla geçici bir dizin oluşturur ve dosyanın zaten mevcut olmadığından emin olur. Yine de dizini kullandıktan sonra silmeyi unutmamalısınız.


25
Kullanmak zorunda kaldımmktemp -d -t <prefix>
— Heath Borders

17
Bu bir OS X vs Linux şeyidir. Her ikisinde de çalışan bir sürüm için bu soruya bakın: unix.stackexchange.com/questions/30091/…
— jwhitlock

2
Ayrıca, temizlemenin de yapıldığından emin olmak için Ortwin'in aşağıdaki cevabına bakın.
— Mathiasdm

5
Neden "Dizini kullandıktan sonra silmeyi hatırlamanız gerekiyor" diyorsunuz? Bu geçici bir dizin kullanma amacını yenmez mi?
— MK Safi

73

Daha sağlam bir çözüm için aşağıdakine benzer bir şey kullanırım. Bu şekilde, komut dosyası çıktıktan sonra geçici dizin her zaman silinir.

Temizleme fonksiyonu EXITsinyal üzerinde yürütülür . Bu, komut dosyası bir yerde iptal etse bile temizleme işlevinin her zaman çağrılmasını garanti eder.

#!/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 betiği dizini buradan .

Bash tuzakları .


26
FreeBSD Dikkat! FreeBSD üzerinde mktemp -p seçeneği yok ve cleanupolacak Geçerli dizinden rf rm!
— madfriend

1
İyi bir nokta, temp dir oluşturulabilir olup olmadığını kontrol etmek için komut dosyasını güncelledi.
— Ortwin Angermeier

1
@madfriend gerçekten? eğer mktempbaşarısız WORK_DIRboş olacak, komutu anlamı sadece olurdu rm -rfhiçbir argüman ile. FreeBSD kullanmıyorum ama rm -rfeşdeğer olsaydı oldukça rm -rf .
— şaşırırdım

@jbg evet, şimdi de bana garip geliyor - gerçekten büyük bir sorun olmamalı. Geçici dizine giden yolun geçerli dizine göreceli olarak hesaplanması için, bu dizinin eski bir sürümünü değiştirmiş olabilirim.
— madfriend

1
Daha iyi hale getirmek için, boş bir dizin önlemek ya da en azından yapmanız bir çözüm kullanarak bir dizin içindeki sorunu içerebilir: 1. TMPWORKDIR=$(basename 'mktemp -d -p /tmp/git/')ve ardından 2. rmdir /tmp/git/"${TMPWORKDIR}". Değişken şimdi boşsa, yine /tmp/git/de tüm sisteme geri dönmeyeceksiniz . Cevapta böyle bir şey düşünün ve memnuniyetle kabul ediyorum. ;)
— Dr Beco

64

Bunun için en sevdiğim tek astar

cd $(mktemp -d)

10
ve rm $(pwd)? : P
— Arran Cudbard-Bell

19
Ayrıca faydalı: pushd $(mktemp -d)...popd
— Ponkadoodle

4
@ ArranCudbard-Bell olmalırm -r $(pwd)
— piggybox

31
@piggybox Açıkçası, kullanırken çok dikkatli olurdum rm -r $(pwd). Geçici dizin oluşturma işleminin herhangi bir nedenle başarısız olma olasılığını göz önünde bulundurun (/ tmp dosya sistemi dolu olabilir veya yalnızca bir hata nedeniyle yeniden okunmuş olabilir?); daha sonra kullanıcının giriş dizininde yapılan ve daha sonra silinecek olan değişiklikleri cd $(mktemp -d)değerlendirir cd.
— Jules

1
if pushd $(mktemp -d || echo BADMPDIR); then ........ ; rm -r $(pwd); popd; fi
— İle

9

Aşağıdaki kod parçası güvenli bir şekilde geçici bir dizin ( -d) oluşturur ve adını TMPDIR. ( TMPDIRDeğişken kullanımına ilişkin bir örnek , daha sonra muhtemelen değiştirilecek orijinal dosyaları depolamak için kullanıldığı kodda gösterilir.)

İlk trapsatır exit 1, belirtilen sinyallerden herhangi biri alındığında komutu yürütür . İkinci trapsatır $TMPDIR, programın çıkışını (normal ve anormal) kaldırır (temizler ). mkdir -dÇıkış tuzağının $TMPDIRbilinmeyen bir durumda yanlışlıkla çalıştırılmasını önlemeyi başardıktan sonra bu tuzakları başlatıyoruz .

#!/bin/bash

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

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

# Make sure it gets removed even if the script exits abnormally.
trap "exit 1"           HUP INT PIPE QUIT TERM
trap 'rm -rf "$TMPDIR"' EXIT

# Example use of TMPDIR:
for f in *.csv; do
    cp "$f" "$TMPDIR"
    # remove duplicate lines but keep order
    perl -ne 'print if ++$k{$_}==1' "$TMPDIR/$f" > "$f"
done

1
Bu, hata işleme için ilginç bir çözüm olsa da, avantajların ve olası eksikliklerin biraz daha açıklanması iyi olurdu.
— Murphy

1.) -ddizinleri kontrol eder. 2.) Bu sinyaller için sonlandırma zaten varsayılan değerdir.
— Ceving
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.