Tìm thư mục tmp chính xác trên nhiều nền tảng


46

Tôi có một tập lệnh cần tạo tập tin tạm thời cho công việc của nó và tự dọn sạch. Câu hỏi của tôi là về việc tìm đúng thư mục cơ sở cho các tập tin tạm thời.

Kịch bản cần hoạt động trên nhiều nền tảng: Git Bash (Windows), Solaris, Linux, OSX. Trên mỗi nền tảng, thư mục temp ưa thích được thể hiện khác nhau:

  • Windows: %TMP%(và có thể %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: được cho là $TMPDIRnhưng dường như chưa được đặt trên nhiều hệ thống tôi đã thử

Vì vậy, trong kịch bản của tôi, tôi đã thêm bản tóm tắt này:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

Điều này có vẻ quá tẻ nhạt. Có cách nào tốt hơn?


6
Chỉ cần sử dụng ${TMPDIR-/tmp}trên Unix thích. TMPDIRcó (bởi hệ thống hoặc quản trị viên hoặc người dùng) để cho bạn biết khi nào không sử dụng /tmpcho các tệp tạm thời.
Stéphane Chazelas

Câu trả lời:


72

Một cách di động hơn một chút để xử lý các tập tin tạm thời là sử dụng mktemp. Nó sẽ tạo các tệp tạm thời và trả lại đường dẫn của chúng cho bạn. Ví dụ:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

Bạn có thể sử dụng nó trong một kịch bản khá dễ dàng:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

Đọc trang người đàn ông, bạn sẽ có thể thiết lập các tùy chọn theo nhu cầu của bạn. Ví dụ:

  • -d tạo một thư mục thay vì một tập tin.
  • -u tạo ra một tên, nhưng không tạo ra bất cứ điều gì.

Sử dụng -ubạn có thể truy xuất thư mục tạm thời khá dễ dàng với ...

$ tmpdir=$(dirname $(mktemp -u))

Thông tin thêm về mktempcó sẵn ở đây .

Chỉnh sửa về Mac OS X: Tôi chưa bao giờ sử dụng hệ thống Mac OSX, nhưng theo nhận xét của Tyilo bên dưới, có vẻ như Mac OSX mktempyêu cầu bạn cung cấp một mẫu (đó là một đối số tùy chọn trên Linux). Trích dẫn:

Ví dụ, mẫu có thể là bất kỳ tên tệp nào có số "X" được thêm vào nó /tmp/temp.XXXX. Dấu "X" được thay thế bằng số quy trình hiện tại và / hoặc kết hợp chữ cái duy nhất. Số lượng tên tệp duy nhất mktemp có thể trả về tùy thuộc vào số lượng "Xs" được cung cấp; sáu "Xs" sẽ dẫn đến mktemp chọn 1 trong 56800235584 (62 ** 6) tên tệp có thể.

Trang man cũng nói rằng việc triển khai này được lấy cảm hứng từ trang man OpenBSD cho mktemp. Do đó, một sự phân kỳ tương tự cũng có thể được quan sát bởi người dùng OpenBSD và FreeBSD (xem phần Lịch sử ).

Bây giờ, như bạn có thể nhận thấy, điều này đòi hỏi bạn phải chỉ định một đường dẫn tệp hoàn chỉnh, bao gồm cả thư mục tạm thời bạn đang tìm kiếm trong câu hỏi của mình. Vấn đề nhỏ này có thể được xử lý bằng cách sử dụng -tchuyển đổi. Mặc dù tùy chọn này dường như yêu cầu một đối số ( prefix), nhưng nó sẽ xuất hiện mktempdựa vào $TMPDIRkhi cần thiết.

Nói chung, bạn sẽ có thể nhận được kết quả tương tự như trên bằng cách sử dụng ...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Mọi phản hồi từ người dùng Mac OS X sẽ được đánh giá rất cao, vì tôi không thể tự mình kiểm tra giải pháp này.


OP đã giải quyết vấn đề này trong một bình luận hiện đã bị xóa; Tôi e rằng tôi không thể cung cấp câu trả lời cho các hệ thống cần gitbashcó giao diện shell, do đó "hơi" của tôi. Tôi thực sự sẽ không thể biết nơi các tệp tạm thời được lưu trữ trên hệ thống Windows ...
John WH Smith

1
ditto đó. Một số điên rồ c:\User\Name\..............\stuff. Và có lẽ có 100 người trong số họ. Tuy nhiên, một số distro linux đang tiến gần đến mức độ điên rồ tương tự /var. Tôi chỉ là tò mò thôi. Nó đánh tôi như một cách kỳ quặc để đặt tất cả - theo kinh nghiệm của tôi, sự thất vọng là rất dễ mang theo, và sự tiện lợi ít như vậy. Câu trả lời rất tốt nào.
mikeerv

1
Cách đây một năm, tôi đã viết một tập lệnh Bash để thao tác các tệp Windows Restore Point hoạt động trên Win2K thông qua WinXP (các phiên bản sau xử lý các công cụ đó khác nhau). Kịch bản của tôi sử dụng WINDOWS/Temphoặc Windows/Templàm thư mục mặc định cho các tệp tạm thời của nó; thư mục đó cũng tồn tại trên các máy Windows 7. Nhưng kịch bản của tôi cho phép người dùng cung cấp một thư mục tạm thời thay thế trên dòng lệnh.
PM 2Ring

Điều này sẽ không hoạt động trên OS X, vì bạn phải cung cấp một mẫu cho mktemp.
Tyilo

1
Vì El Capitan, mktempchỉ hoạt động: đơn giản mktemptrả về một tệp và mktemp -dtrả về một thư mục; không yêu cầu mẫu Các nhãn hiệu không được cập nhật mặc dù.
Franklin Yu

9

Nếu bạn đang tìm kiếm điều tương tự trong ít dòng hơn ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

Bạn có thể viết điều này trong một.


Bạn có lẽ cũng nên kiểm tra nếu nó có thể ghi.
frostschutz

@janos: Và nếu tất cả các cách khác đều thất bại, hãy yêu cầu người dùng cung cấp đường dẫn cho các tệp tạm thời hoặc cho phép họ chỉ định một đường dẫn trên dòng lệnh.
PM 2Ring

6

Bạn có thể làm:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

Shell sẽ tìm thấy một thư mục thực thi trong một trong 4 lựa chọn thay thế hoặc thoát với một lỗi có ý nghĩa. Tuy nhiên, POSIX định nghĩa $TMPDIRbiến (cho các hệ thống XCU) :

TMPDIR Biến này sẽ đại diện cho một tên đường dẫn của một thư mục có sẵn cho các chương trình cần một nơi để tạo các tệp tạm thời.

Nó cũng đòi hỏi /tmpcon đường.


1
Đây là câu trả lời đúng duy nhất ở đây IMO. Không biết nó đang làm gì ở phía dưới mà không có phiếu bầu ...
Graeme

2
@Graeme: có lẽ vì nó hoàn toàn không thể đọc được?
ssc

Tôi đã nâng cấp nhưng sau đó rút lại nó-- vâng, câu trả lời này là một mớ hỗn độn, Nó dường như là một bài hát hữu ích, nhưng không rõ đoạn mã đang cố làm gì - dòng đầu tiên là một nhận xét và dòng thứ hai một là một lỗi (trong bash, anyway). Có thể sử dụng một số công việc.
Don nở

Ồ tôi hiểu rồi, phiên bản đầu tiên của câu trả lời đã rõ ràng hơn (vẫn là một lỗi trên dòng thứ 2 nếu bạn thực sự cố gắng chạy nó) ... và sau đó một loạt các chỉnh sửa đã hoàn toàn bỏ qua mẫu mã vì vậy bây giờ nó vô nghĩa. Có thể sử dụng một hoặc hai lượt khác :-)
Don hatch
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.