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.