Các tập tin tạm thời nên được lưu vào / tmp hoặc thư mục làm việc hiện tại?


76

Tôi có một chương trình cần tạo tập tin tạm thời. Nó được viết cho máy cụm.

Nếu tôi đã lưu các tệp đó vào một thư mục tạm thời trên toàn hệ thống (ví dụ /tmp:), một số người dùng đã phàn nàn chương trình không thành công vì họ không có quyền truy cập / tmp thích hợp. Nhưng nếu tôi lưu các tệp đó vào thư mục làm việc, những người dùng đó cũng phàn nàn rằng họ không muốn xem các tệp bí ẩn đó.

Cái nào là thực hành tốt hơn? Tôi có nên nhấn mạnh rằng tiết kiệm /tmplà cách tiếp cận phù hợp và bảo vệ mọi thất bại là "hoạt động như dự định" (nghĩa là yêu cầu quản trị viên của bạn cho phép / quyền truy cập phù hợp)?


3
kiểm tra xem chương trình có quyền truy cập không và nếu không tìm thấy một thư mục tạm thời khác
ratchet freak

24
Nếu quản trị viên của bạn làm hỏng quyền truy cập, anh ấy chắc chắn nên sửa nó. Bạn sẽ làm gì nếu quản trị viên của bạn quên thêm quyền thực thi cho chương trình của bạn?
Doc Brown

7
Bạn sẽ không tìm thấy / tmp trên hầu hết các hệ thống windows, nhưng có một cuộc gọi HĐH sẽ cho bạn biết nơi đặt các tệp tạm thời.
Ian

28
Nếu một số người không có quyền truy cập /tmpvào hệ thống giống Unix, thì nó bị định cấu hình sai. Các siêu người dùng nên làm một cái gì đó như chmod 1777 /tmp.
musiphil

12
Coi chừng $ TMPDIR có thể trỏ đến một đường dẫn khác /tmp/, mà bạn nên sử dụng thay thế. Xem một số câu trả lời;)
marcelm

Câu trả lời:


141

Các tệp tạm thời phải được lưu trữ vào thư mục tạm thời của hệ điều hành vì một số lý do:

  • Hệ điều hành giúp dễ dàng tạo các tệp đó trong khi vẫn đảm bảo rằng tên của chúng là duy nhất .

  • Hầu hết các phần mềm sao lưu đều biết các thư mục chứa các tệp tạm thời là gì và bỏ qua chúng. Nếu bạn sử dụng thư mục hiện tại, nó có thể có ảnh hưởng quan trọng đến kích thước của các bản sao lưu gia tăng nếu việc sao lưu được thực hiện thường xuyên.

  • Thư mục tạm thời có thể nằm trên một đĩa khác hoặc trong RAM, giúp truy cập đọc-ghi nhanh hơn nhiều .

  • Các tệp tạm thời thường bị xóa trong quá trình khởi động lại (nếu chúng nằm trong ramdisk, chúng chỉ đơn giản là bị mất). Điều này giúp giảm nguy cơ tăng trưởng vô hạn nếu ứng dụng của bạn không phải lúc nào cũng xóa các tệp tạm thời một cách chính xác (ví dụ sau khi gặp sự cố).

    Làm sạch các tệp tạm thời từ thư mục làm việc có thể dễ dàng trở nên lộn xộn nếu các tệp được lưu trữ cùng với các tệp ứng dụng và người dùng. Bạn có thể giảm thiểu vấn đề này bằng cách tạo một thư mục riêng trong thư mục hiện tại, nhưng điều này có thể dẫn đến một vấn đề khác:

  • Độ dài đường dẫn có thể quá dài trên một số nền tảng. Chẳng hạn, trên Windows, giới hạn đường dẫn cho một số API, khung và ứng dụng rất tệ , điều đó có nghĩa là bạn có thể dễ dàng đạt giới hạn đó nếu thư mục hiện tại đã nằm sâu trong hệ thống phân cấp cây và tên của các tệp tạm thời của bạn quá dài.

  • Trên các máy chủ, việc theo dõi sự tăng trưởng của thư mục tạm thời thường được thực hiện ngay lập tức. Nếu bạn sử dụng một thư mục khác, nó có thể không được theo dõi và giám sát toàn bộ đĩa sẽ không giúp dễ dàng nhận ra rằng đó là các tệp tạm thời chiếm vị trí ngày càng nhiều.

Đối với các lỗi truy cập bị từ chối, hãy đảm bảo bạn để hệ điều hành tạo một tệp tạm thời cho bạn. Ví dụ, hệ điều hành có thể biết rằng đối với một người dùng nhất định, một thư mục khác /tmphoặc C:\Windows\tempnên được sử dụng; do đó, bằng cách truy cập trực tiếp vào các thư mục đó, bạn thực sự có thể gặp phải lỗi từ chối truy cập.

Nếu bạn nhận được quyền truy cập bị từ chối ngay cả khi sử dụng cuộc gọi hệ điều hành, điều đó chỉ có nghĩa là máy bị cấu hình kém; điều này đã được giải thích bởi Blrfl . Tùy thuộc vào quản trị hệ thống để cấu hình máy; bạn không phải thay đổi ứng dụng của bạn.

Tạo tập tin tạm thời là đơn giản trong nhiều ngôn ngữ. Một vài ví dụ:

  • Bash:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
    
  • Con trăn:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
    
  • C #:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
    
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
    
  • Ruby:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close
    

Lưu ý rằng trong một số trường hợp, chẳng hạn như trong PHP và Ruby, tệp sẽ bị xóa khi đóng tay cầm. Đó là một lợi ích bổ sung của việc sử dụng các thư viện đi kèm với ngôn ngữ / khung.


2
Ý bạn là gì khi "đảm bảo rằng bạn để hệ điều hành tạo một tệp tạm thời cho bạn". Vì vậy, thay vì ví dụ fopen("/tmp/mytmpfile", "w");tôi nên thực hiện một số cuộc gọi hệ thống để xử lý các tập tin tạm thời?
simon

30
@gurka: Bạn nên gọi tmpfile(3)để tạo các tệp tạm thời hoặc ít nhất là gọi mktemp(3)để tạo tên tệp.
TMN

3
@TMN: Chúng chỉ là các chức năng thư viện chạy trong không gian người dùng và chúng không có phép thuật nào để vượt qua lỗi cấp phép do hệ điều hành đưa ra.
musiphil

25
@musiphil Cả tmpfile và mktemp đều sử dụng các biến ngoài để xác định đường dẫn cho các tệp tạm thời. Chúng có thể đã được thiết lập để trỏ đến thư mục khác ngoài / tmp /, có lẽ là thư mục theo người dùng. Cố gắng tạo tên tệp theo cách thủ công trong / tmp / có thể không thành công, trong khi tmpfile và mktemp sẽ trả về các đường dẫn hợp lệ.
đường ống

2
@musiphil: Tôi chưa bao giờ nói rằng họ sẽ khắc phục vấn đề cấp phép, tôi đã trả lời câu hỏi của anh ấy về việc sử dụng các cuộc gọi hệ thống để tạo các tệp.
TMN

33

Tôi có nên khẳng định lưu vào / tmp là cách tiếp cận phù hợp và bảo vệ cho mọi thất bại là "hoạt động như dự định" (nghĩa là hỏi quản trị viên của bạn để có quyền truy cập phù hợp)?

Có những tiêu chuẩn cho điều này, và điều tốt nhất bạn có thể làm là tuân thủ chúng.

POSIX, được theo dõi bởi khá nhiều hệ điều hành không phải máy tính lớn có ý nghĩa mà bạn có thể gặp phải, có các quy định để tạo các tệp tạm thời có tên duy nhất trong một thư mục sử dụng các giá trị mặc định có thể được cấu hình lại bởi môi trường:

  • stdio.hTiêu đề C có thể tùy ý bao gồm một P_tmpdirmacro đặt tên thư mục tạm thời của hệ thống.
  • TMPDIRlà biến môi trường chính tắc để thay đổi vị trí của các tệp tạm thời. Trước POSIX, đã có các biến khác được sử dụng, vì vậy tôi có xu hướng đi theo biến đầu tiên hoặc TMP, TEMPDIRTEMPcó giá trị, punt và sử dụng mặc định hệ thống nếu không có biến nào tồn tại.
  • Các chức năng mkstemp()tempfile()sẽ tạo ra các tập tin tạm thời duy nhất.

Nếu người dùng của bạn đang bị từ chối khả năng tạo các tệp tạm thời, hệ thống sẽ bị định cấu hình sai hoặc quản trị viên không làm rõ chính sách của họ là gì đối với những thứ đó. Trong những trường hợp đó, bạn sẽ rất chắc chắn khi nói rằng chương trình của bạn tuân thủ tiêu chuẩn về tính di động được thiết lập tốt và hành vi của nó có thể được thay đổi bằng cách sử dụng các biến môi trường mà tiêu chuẩn chỉ định.


P_tmpdirkhông phải là một phần stdio.hnhư được định nghĩa bởi đặc tả ngôn ngữ C. Nó có thể được xác định bởi POSIX hoặc SVID.
musiphil

1
@musiphil: Theo ngụ ý của câu trả lời (hiện đã được làm rõ), đó là một phần của POSIX. (Về mặt kỹ thuật, nó là một X / Open Hệ thống mở rộng mà POSIX đưa See. Pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl

Hoàn toàn đồng ý với tất cả những điều trên. Một ví dụ điển hình là các hệ thống Linux có pam_tmpdir- bộ này TMPDIRTMPkhác biệt đối với mỗi người dùng, vì sự mạnh mẽ và riêng tư. Cũng rất hữu ích khi có thể thiết lập TMPDIRmột lệnh duy nhất - nếu bạn có thư mục tạm thời thông thường của mình trong hệ thống tệp RAM để tăng tốc, bạn có thể cần thực hiện việc này đối với các lệnh tạo các tệp tạm thời khổng lồ (ví dụ như một người khổng lồ sort). Đừng bỏ qua các tiêu chuẩn / quy ước mà người dùng của bạn mong đợi!
Toby Speight

Chắc chắn kiểm tra môi trường cho vị trí của các tệp tạm thời và không bao giờ mã cứng / tmp. Bởi vì một tmp được chia sẻ có vấn đề về bảo mật, một giảm thiểu mà tôi thường thấy là tạo các thư mục theo người dùng / tmp mà không có quyền đọc-ghi cho bất kỳ ai khác. Nó loại bỏ các điều kiện chủng tộc có thể và các cuộc tấn công symlink.
Zan Lynx

9

Thư mục temp-file-phụ thuộc hệ điều hành / môi trường cao. Ví dụ, một web-server-temp dir được tách biệt khỏi os-temp-dir vì lý do bảo mật.

Trong ms-windows, mọi người dùng đều có temp-dir riêng.

bạn nên sử dụng createTempFile () cho việc này nếu một hàm như vậy có sẵn.


1
Chỉ cần lưu ý về các hạn chế hệ điều hành ẩn trong Windows. Chúng tôi đã phát hiện ra một cách khó khăn là số lượng tệp tối đa trong một thư mục bị giới hạn ở mức 65.565. Chắc chắn, đó là rất nhiều tập tin, và chắc chắn, bạn không bao giờ nên nghĩ rằng có nhiều tập tin được đặt xung quanh. Nhưng bạn có chắc chắn rằng mọi ứng dụng sẽ tự dọn dẹp một cách kịp thời và cư xử đúng mực?
Mike Hofer

Ah, tôi đã thấy bình luận của bạn quá muộn. Tôi chỉ viết tương tự ở trên. BTW giới hạn chủ yếu là do các cơ chế của hàm GetTimeFileName (), không phải NTFS. Giới hạn thư mục mà bạn đề cập chỉ áp dụng cho FAT32 .
JensG

9

Các câu trả lời trước, mặc dù đúng, không hợp lệ đối với hầu hết các cụm máy tính quy mô lớn.

Các cụm máy tính không phải lúc nào cũng tuân theo các quy ước tiêu chuẩn cho máy móc, thường là vì lý do chính đáng, và không có lý do nào để thảo luận về nó với các hệ thống.

Thư mục hiện tại của bạn đang đề cập đến hệ thống tệp trung tâm, được truy cập qua mạng. Điều này không chỉ chậm, mà còn tăng tải cho hệ thống cho những người dùng còn lại, vì vậy bạn không nên sử dụng nó trừ khi bạn không viết nhiều và bạn có thể phục hồi từ nó nếu công việc gặp sự cố.

Các nút tính toán có ổ cứng riêng, đó là hệ thống tệp nhanh nhất hiện có và những gì bạn nên sử dụng. Các tài liệu cụm nên nói với bạn nó là gì, thường /scratch, /tmp/[jobid]hoặc một số không biến môi trường tiêu chuẩn ( $SNIC_TMPmột trong những cái tôi sử dụng).

Vì vậy, những gì tôi khuyên là làm cho nó có thể cấu hình được. Mặc định có thể là mặc định đầu tiên bạn có quyền truy cập ghi vào:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Nhưng mong đợi tỷ lệ thành công thấp với phương pháp này và đảm bảo phát ra một cảnh báo lớn về chất béo.

Chỉnh sửa: Tôi sẽ thêm một lý do khác để buộc nó phải do người dùng thiết lập. Một trong những cụm của tôi đã $TMPDIRđược đặt thành /scratch, đó là người dùng có thể ghi và trên ổ cứng cục bộ. Nhưng, tài liệu nói rằng bất cứ điều gì bạn viết bên ngoài /scratch/[jobid]có thể bị xóa tại bất kỳ thời điểm nào, ngay cả khi đang chạy. Vì vậy, nếu bạn làm theo các tiêu chuẩn và tin tưởng $TMPDIR, bạn sẽ gặp phải các sự cố ngẫu nhiên, rất khó để gỡ lỗi. Vì vậy, bạn có thể chấp nhận $TMPDIR, nhưng không tin tưởng nó.

Một số cụm khác có biến này được cấu hình đúng, vì vậy bạn có thể thêm một tùy chọn để tin tưởng rõ ràng $TMPDIR, nếu không, sẽ phát ra một cảnh báo lớn, béo.


1
Những câu trả lời chính xác là gì?
Tulains Córdova

2
Vì vậy, điều bạn đang nói ở đây là bởi vì một số cụm không thực hiện bước tầm thường tuân thủ một tiêu chuẩn được thiết lập tốt để nói với các chương trình nơi ghi tệp tạm thời của chúng, đó là một tùy chỉnh cụ thể theo cụm cụ thể cho mỗi chương trình. Trà khá yếu nếu bạn hỏi tôi.
Blrfl

@Blrfl bạn có thể tạo sóng theo tiêu chuẩn bao nhiêu tùy ý và viết mã tuân thủ hoàn toàn tốt với chúng và luôn gặp sự cố; bạn có thể cố gắng chiến đấu với các hệ thống của mỗi cụm bạn sử dụng; hoặc bạn có thể chấp nhận đức tin của bạn và làm cho nó có thể cấu hình. Ngoài ra, trong HPC, người ta thường cần phải điều chỉnh mã theo các chi tiết cụ thể của cụm (RAM có sẵn, tốc độ tương đối của hệ thống tệp, triển khai MPI, tài nguyên sẵn có chung ...), không có "một kích thước phù hợp với tất cả".
Davidmh

@Davidmh: Đã hiểu, nhưng không phải là vấn đề. Các tiêu chuẩn làm cho nó có thể cấu hình theo một cách không đáng kinh ngạc. Nếu tôi lấy mã tuân thủ đã biết đến một cụm nơi tiêu chuẩn không được tuân theo, tôi phải đặt mã ở đúng một nơi, chẳng hạn như tại điểm vào. Đó là một điều ít hơn trong phần còn lại của mã để kiểm toán, sửa đổi và có nguy cơ bị sai.
Blrfl

1

Đối với nhiều ứng dụng, bạn nên xem xét đưa các tệp tạm thời vào $XDG_RUNTIME_DIRhoặc $XDG_CACHE_HOME(các thư mục XDG khác dành cho các tệp không tạm thời ). Để biết hướng dẫn về cách tính toán chúng nếu chúng không được truyền một cách rõ ràng trong môi trường, hãy xem thông số dựa trên XDG hoặc tìm một thư viện đã thực hiện phần đó.

Lưu ý, tuy nhiên, đó $XDG_RUNTIME_DIRlà một bổ sung mới và không có dự phòng tiêu chuẩn cho các hệ thống cũ do lo ngại về bảo mật.

Nếu cả hai không phù hợp, thì đó /tmplà nơi chính xác. Bạn không bao giờ nên cho rằng thư mục hiện tại là có thể ghi.


-2

Điều này giống như một sự thay thế, nhưng bạn có thể hủy liên kết () tệp ngay sau fopen (). Nó phụ thuộc vào mô hình sử dụng của nguồn.

Hủy liên kết các tệp, nếu có thể được thực hiện, sẽ giúp một số cách:

  • tập tin không được nhìn thấy - người dùng không nhìn thấy nó.
  • không thể nhìn thấy tệp từ các quy trình khác - không có khả năng quy trình khác sửa đổi tệp do nhầm lẫn.
  • dễ dàng dọn dẹp nếu chương trình sụp đổ.

Các tệp phải được tạo trong / tmp. Nếu người dùng không có quyền tạo tệp ở đó, điều này có nghĩa là hệ thống bị cấu hình sai.

Tập tin không thể được tạo trong thư mục nhà của người dùng. Rất nhiều người dùng, chẳng hạn như "không ai", "dữ liệu www" và nhiều người khác, không có quyền ghi vào thư mục nhà của họ, hoặc họ thậm chí còn bị chroot () - ed. Lưu ý rằng ngay cả trong môi trường chroot / tmp vẫn tồn tại.


Mặc dù điều này có thể là một ý tưởng tốt nói chung, nhưng nó không giúp người dùng thiếu quyền ghi vào thư mục mà tệp sẽ được tạo trong.
5gon12eder

4
Nó cũng không trả lời câu hỏi, đó là nơi để đặt các tập tin tạm thời.
Blrfl

Tôi tin rằng câu trả lời của tôi là bằng cách nào đó quan trọng. Tôi đã chỉnh sửa, có lẽ là rõ ràng hơn theo cách này.
Nick
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.