Câu trả 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 (tất cả các phiên bản trước Mac OS X 10.11), mà không cần mã hóa $TMPDIR
hoặc /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Lệnh GNU mktemp không yêu cầu đối số. Plain mktemp
sẽ 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 -d
sẽ 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.XXXXXXXXXX
cho tên của thư mục con (hoặc tệp). Để tùy chỉnh mẫu này, -t
tù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 -t
tù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 -t
tùy chọn có nghĩa là một cái gì đó khác. Các -t
tù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 example
có thể tạo example.zEJZWCTQ
trong 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.XXXXXXXX
trong 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, $TMPDIR
luô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 $TMPDIR
hoặ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 1
phả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 mytmpdir
tiề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).
mktemp -d
trê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
Bạn phải cung cấp một mẫu. mktemp -d /tmp/foo.XXXX
nê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.
$TMPDIR
khi 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.
Thay đổi --directory
thành -d
. Cái trước là một GNU-ism, nhưng GNU mktemp
từ coreutils cũng hỗ trợ -d
. Các mktemp
trong OS X cũng giống như từ BSD, vì vậy -d
nên được khá linh động trong hệ thống mà thực sự xuất xưởng một mktemp
chương trình.
mktemp -d
, và nó cũng không hoạt động.
mktemp
OS 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.
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?
mktemp
trê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
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 X
s nào trong mẫu.mktemp
cho 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ố X
s phải là 6.Lưu ý rằng -t
khô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)"