Làm thế nào để tạo một thư mục tạm thời?


229

Tôi sử dụng để tạo một tempfile, xóa nó và tạo lại nó như một thư mục:

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

Vấn đề là, một quá trình khác có thể có cùng tên X, nếu nó vô tình thực thi tempfile sau một quá trình rm -f Xvà ngay trước đó mkdir X.

Câu trả lời:


341

Sử dụng mktemp -d. Nó tạo một thư mục tạm thời với một tên ngẫu nhiên và đảm bảo rằng tệp đó không tồn tại. Bạn cần nhớ xóa thư mục sau khi sử dụng nó.


25
Tôi đã phải sử dụngmktemp -d -t <prefix>
Heath B ranh giới

17
Đây là một điều OS X vs Linux. Xem câu hỏi này cho một phiên bản hoạt động trên cả hai: unix.stackexchange.com/questions/30091/ mẹo
jwhitlock

2
Ngoài ra, hãy xem câu trả lời dưới đây của Ortwin, vì điều đó đảm bảo việc dọn dẹp cũng được thực hiện.
Mathiasdm

5
Tại sao bạn nói "Bạn cần nhớ xóa thư mục sau khi sử dụng nó."? Điều đó có làm thất bại mục đích sử dụng thư mục tạm thời không?
MK Safi

73

Đối với một giải pháp mạnh mẽ hơn, tôi sử dụng một cái gì đó như sau. Bằng cách đó, thư mục tạm thời sẽ luôn bị xóa sau khi thoát khỏi tập lệnh.

Chức năng dọn dẹp được thực hiện trên EXITtín hiệu. Điều đó đảm bảo rằng chức năng dọn dẹp luôn được gọi, ngay cả khi tập lệnh hủy bỏ ở đâu đó.

#!/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
...

Thư mục của bash script từ đây .

Bẫy Bash .


26
Cảnh báo FreeBSD! mktemp trên FreeBSD không có tùy chọn -p và cleanupsẽ rm -rf thư mục hiện tại của bạn!
bạn trai

1
Điểm hay, cập nhật tập lệnh để kiểm tra xem thư mục tạm thời có thể được tạo không.
Ortwin Angermeier

1
@madfriend thật sao? nếu mktempthất bại, WORK_DIRsẽ trống, có nghĩa là lệnh sẽ rm -rfkhông có đối số. Tôi không sử dụng FreeBSD nhưng tôi khá ngạc nhiên nếu rm -rftương đương vớirm -rf .
jbg

@jbg vâng, nó có vẻ kỳ lạ với tôi bây giờ - nó không phải là một vấn đề thực sự lớn. Tôi có thể đã điều chỉnh một phiên bản cũ của tập lệnh này để đường dẫn đến thư mục tạm thời được tính tương đối với thư mục hiện tại, dẫn đến việc <s> tuyệt chủng của nhân loại </ s> loại bỏ thư mục hiện tại.
bạn điên

1
Để làm cho nó tốt hơn, bạn có thể tránh một thư mục trống hoặc ít nhất có chứa vấn đề trong một thư mục bằng cách sử dụng một giải pháp mà bạn làm: 1. TMPWORKDIR=$(basename 'mktemp -d -p /tmp/git/')và sau đó 2 rmdir /tmp/git/"${TMPWORKDIR}".. Nếu bây giờ biến trống, bạn vẫn sẽ quay lại /tmp/git/không cho toàn bộ hệ thống. Hãy xem xét một cái gì đó như thế này trong câu trả lời và tôi sẽ vui lòng đồng ý. ;)
Bác sĩ Beco

64

Lớp lót yêu thích của tôi cho việc này là

cd $(mktemp -d)

10
rm $(pwd)? : P
Arran Cudbard-Bell 16/12/14

19
cũng hữu ích: pushd $(mktemp -d)...popd
Ponkadoodle

4
@ ArranCudbard-Bell nênrm -r $(pwd)
piggybox

31
@piggybox Thành thật mà nói, tôi rất thận trọng khi sử dụng rm -r $(pwd). Xem xét khả năng tạo thư mục tạm thời không thành công vì bất kỳ lý do gì (có thể hệ thống tập tin / tmp đã đầy hoặc đã được đọc lại chỉ đọc do lỗi?); sau đó cd $(mktemp -d)sẽ đánh giá cdnhững thay đổi đối với thư mục chính của người dùng, sau đó sẽ bị xóa.
Jules

1
Nó có thể an toàn vớiif pushd $(mktemp -d || echo BADMPDIR); then ........ ; rm -r $(pwd); popd; fi
AndreyS Scherbakov

9

Đoạn mã sau sẽ tạo một thư mục tạm thời ( -d) một cách an toàn và lưu tên của nó vào TMPDIR. (Một ví dụ sử dụng TMPDIRbiến được hiển thị sau trong mã nơi nó được sử dụng để lưu trữ các tệp gốc sẽ có thể được sửa đổi.)

Dòng đầu tiên trapthực thi exit 1lệnh khi nhận được bất kỳ tín hiệu nào được chỉ định . Dòng thứ hai traploại bỏ (dọn sạch) $TMPDIRlối ra của chương trình (cả bình thường và bất thường). Chúng tôi khởi tạo các bẫy này sau khi chúng tôi kiểm tra xem mkdir -dđã thành công để tránh việc vô tình thực hiện bẫy thoát $TMPDIRtrong trạng thái không xác định.

#!/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
Mặc dù đây là một giải pháp thú vị cho việc xử lý lỗi, nhưng giải thích thêm một chút về những ưu điểm và những thiếu sót có thể sẽ tốt đẹp.
Murphy

1.) -dkiểm tra các thư mục. 2.) Chấm dứt đã là mặc định cho các tín hiệu.
ceving
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.