Khắc phục hoặc thay thế cho mktemp trong OS X


73

Tôi đang xem một tập lệnh bash mà người khác đã viết sử dụng mktemp:

TEMP=`mktemp --directory`

Tuy nhiên, dòng này không hoạt động trên máy của tôi (OS X 10.6).

Làm cách nào để sửa dòng này sao cho tương thích chéo-un * x-like-platform? EDIT: Một lệnh thay thế cũng sẽ là đủ.

Câu trả lời:


109

Sau đây là những gì tôi đã sử dụng để tạo một thư mục tạm thời hoạt động trên cả Linux và Darwin (tất cả các phiên bản trước Mac OS X 10.11), mà không cần mã hóa $TMPDIRhoặc /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

Lý lịch:

Lệnh GNU mktemp không yêu cầu đối số. Plain mktempsẽ hoạt động và tạo một tệp tạm thời trong thư mục tạm thời của hệ thống.

Plain mktemp -dsẽ tạo một thư mục thay vì một tệp, đó là những gì bạn muốn sử dụng trên Linux.

(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..

Theo mặc định, GNU mktemp sử dụng khuôn mẫu tmp.XXXXXXXXXXcho tên của thư mục con (hoặc tệp). Để tùy chỉnh mẫu này, -ttùy chọn có thể được sử dụng.

Mktemp của OSX không có mẫu mặc định và yêu cầu một mẫu phải được chỉ định. Thật không may, trong đó GNU mktemp lấy mẫu làm -ttùy chọn, trên OSX, điều này được thông qua dưới dạng đối số vị trí. Thay vào đó, mktemp của OSX có một -ttùy chọn có nghĩa là một cái gì đó khác. Các -ttùy chọn trên OSX được ghi chép lại như một "tiền tố" cho mẫu. Nó được mở rộng thành {prefix}.XXXXXXXX, do đó, nó tự động thêm X vào nó (ví dụ mktemp -d -t examplecó thể tạo example.zEJZWCTQtrong thư mục tạm thời).

Tôi rất ngạc nhiên khi thấy rằng trong nhiều môi trường Linux, $TMPDIRđược không thiết lập theo mặc định. Nhiều chương trình CLI hỗ trợ nó khi được đặt, nhưng vẫn cần mặc định cho /tmp. Điều này có nghĩa là chuyển $TMPDIR/example.XXXXXXXXđến mktemp hoặc mkdir là nguy hiểm vì nó có thể tạo ra /example.XXXXXXXXtrong thư mục gốc của đĩa cục bộ (do $ TMPDIR không được đặt và trở thành một chuỗi rỗng).

Trên OSX, $TMPDIRluôn được đặt và (ít nhất là trong vỏ mặc định), nó không được đặt thành /tmp(đó là một liên kết tượng trưng /private/tmp) mà là /var/folders/dx/*****_*************/T. Vì vậy, bất cứ điều gì chúng ta làm cho OSX, nên tôn trọng hành vi mặc định đó.

Tóm lại, sau đây là những gì tôi đã sử dụng để tạo một thư mục tạm thời hoạt động trên cả Linux và Darwin (Mac OS X), mà không cần mã hóa cứng $TMPDIRhoặc /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

Phần đầu tiên dành cho Linux. Lệnh này sẽ thất bại trên Darwin (Mac OS X) với mã trạng thái lỗi 1phản hồi với "cách sử dụng: ...". Đó là lý do tại sao chúng tôi bỏ qua thiết bị lỗi chuẩn và thay vào đó thực thi biến thể Mac. Các mytmpdirtiền tố chỉ được sử dụng trên Mac (nơi tùy chọn đó được yêu cầu phải được thiết lập).


12
Thật tuyệt Đôi khi OS X hành vi khác nhau là gây phiền nhiễu.
Therealmarv

6
@therealmarv Tôi muốn nói, luôn luôn.
Nikita Volkov

10
Tôi mới chạy mktemp -dtrên OS X 10.11.5 El Capitan và nó hoạt động như mong đợi file $(mktemp -d):: /var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
Heath

2
Vâng. Tôi đã rất ngạc nhiên khi bạn biết rằng đây chỉ là Worked ™.
Heath Biên giới

1
Ngoài ra nếu bạn chạy mktemp -d -t 'mytmpdir'trên Linux (được thử nghiệm mktemptừ coreutils 8.26), nó hoạt động như mong đợi.

15

Bạn phải cung cấp một mẫu. mktemp -d /tmp/foo.XXXXnên làm việc. Tôi chưa từng thấy --directory. Các --gợi ý rằng nó là một phần mở rộng GNU.


6
Nếu bạn muốn sử dụng $TMPDIRkhi có sẵn, hãy làm mktemp -d "${TMPDIR:-/tmp}"/foo.XXXX. Nó hoạt động trong bash trên Mac và dash trên Debian, vì vậy nó có vẻ như là di động.
Tom Anderson

9

Thay đổi --directorythành -d. Cái trước là một GNU-ism, nhưng GNU mktemptừ coreutils cũng hỗ trợ -d. Các mktemptrong OS X cũng giống như từ BSD, vì vậy -dnên được khá linh động trong hệ thống mà thực sự xuất xưởng một mktempchương trình.


Tôi vừa thử mktemp -d, và nó cũng không hoạt động.
nỗ lực.

1
Kyle có câu trả lời hoàn chỉnh. Trên mktempOS X yêu cầu một mẫu. Tập lệnh bạn đang sử dụng giả định các quy ước GNU, sử dụng một mẫu mặc định nếu không được cung cấp.
James Sneeringer

Vấn đề là unix dự kiến ​​sẽ XXXXXđược cung cấp trong mẫu trong đó OS X không chắc chắn có cờ mẫu tương thích không?
dùng3467349

2
mktemptrên OS X 10.11.5 El Capitan hoạt động với tôi file $(mktemp -d)::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
Heath

4
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktempđối với BSD (bao gồm OSX ) yêu cầu một mẫu, nhưng nó cho phép bất kỳ số lượng Xs nào trong mẫu.
  • (GNU) mktempcho Linux không yêu cầu một mẫu, tuy nhiên, nếu một mẫu được chỉ định, thì số Xs phải là 6.

Lưu ý rằng -tkhông được dùng cho GNUmktemp , vì vậy mã chứng minh tương lai hơn sẽ là

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
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.