ควรบันทึกไฟล์ชั่วคราวไว้ใน / tmp หรือไดเรกทอรีทำงานปัจจุบันหรือไม่


76

ฉันมีโปรแกรมที่ต้องการสร้างไฟล์ชั่วคราว มันถูกเขียนขึ้นสำหรับเครื่องคลัสเตอร์

หากฉันบันทึกไฟล์เหล่านั้นไปยังไดเรกทอรีชั่วคราวทั้งระบบ (เช่น:) /tmpผู้ใช้บางรายบ่นว่าโปรแกรมล้มเหลวเพราะไม่สามารถเข้าถึง / tmp ได้อย่างเหมาะสม แต่ถ้าฉันบันทึกไฟล์เหล่านั้นไปยังไดเรกทอรีใช้งานผู้ใช้เหล่านั้นก็บ่นว่าพวกเขาไม่ต้องการเห็นไฟล์ลึกลับเหล่านั้น

แบบไหนดีกว่ากัน ฉันควรยืนยันว่าการบันทึก/tmpเป็นวิธีการที่ถูกต้องและป้องกันความล้มเหลวในฐานะ "ทำงานตามที่ตั้งใจ" (เช่นขอให้ผู้ดูแลระบบของคุณขออนุญาต / เข้าถึงที่เหมาะสม)


3
ตรวจสอบว่าโปรแกรมมีการเข้าถึงหรือไม่และไม่พบคนอื่นชั่วคราว
วงล้อประหลาด

24
หากผู้ดูแลระบบของคุณทำให้สิทธิ์การเข้าถึงหมดไปเขาควรแก้ไขมันอย่างแน่นอน คุณจะทำอย่างไรถ้าผู้ดูแลระบบของคุณลืมเพิ่มสิทธิในการใช้งานโปรแกรมของคุณ
Doc Brown

7
คุณจะไม่พบ / tmp บนระบบ windows ส่วนใหญ่ แต่มีการเรียกใช้ระบบปฏิบัติการที่จะบอกคุณว่าจะวางไฟล์ temp ไว้ที่ใด
เอียน

28
หากบางคนไม่สามารถเข้าถึง/tmpระบบที่มีลักษณะคล้าย Unix แสดงว่ามีการกำหนดค่าผิดพลาด superuser chmod 1777 /tmpควรทำสิ่งที่ชอบ
musiphil

12
ระวังว่า $ TMPDIR อาจชี้ไปที่เส้นทาง/tmp/อื่นซึ่งคุณควรใช้แทน ดูคำตอบบางส่วน;)
marcelm

คำตอบ:


141

ไฟล์ชั่วคราวจะต้องเก็บไว้ในไดเรกทอรีชั่วคราวของระบบปฏิบัติการด้วยเหตุผลหลายประการ:

  • ระบบปฏิบัติการที่จะทำให้มันง่ายมากที่จะสร้างไฟล์เหล่านั้นขณะที่มั่นใจว่าชื่อของพวกเขาจะไม่ซ้ำกัน

  • ซอฟต์แวร์สำรองข้อมูลส่วนใหญ่รู้ว่าอะไรคือไดเรกทอรีที่มีไฟล์ชั่วคราวและข้ามไป หากคุณใช้ไดเรกทอรีปัจจุบันอาจมีผลกระทบที่สำคัญกับขนาดของการสำรองข้อมูลเพิ่มเติมหากมีการสำรองข้อมูลบ่อยครั้ง

  • ไดเรกทอรีชั่วคราวอาจอยู่ในดิสก์ที่แตกต่างกันหรือใน RAM ทำให้การเข้าถึงการอ่าน - เขียนเร็วขึ้นมาก

  • ไฟล์ชั่วคราวมักจะถูกลบระหว่างการรีบู๊ต (หากอยู่ใน ramdisk ไฟล์จะหายไป) วิธีนี้ช่วยลดความเสี่ยงของการเติบโตไม่สิ้นสุดหากแอปของคุณไม่ได้ลบไฟล์ชั่วคราวอย่างถูกต้อง (ตัวอย่างเช่นหลังจากเกิดข้อผิดพลาด)

    การทำความสะอาดไฟล์ temp จากไดเรกทอรีการทำงานอาจทำให้เกิดความยุ่งเหยิงได้ง่ายหากไฟล์นั้นถูกจัดเก็บพร้อมกับแอปพลิเคชันและไฟล์ผู้ใช้ คุณสามารถลดปัญหานี้ได้โดยสร้างไดเรกทอรีแยกต่างหากภายในไดเรกทอรีปัจจุบัน แต่สิ่งนี้อาจนำไปสู่ปัญหาอื่น:

  • ยาวเส้นทางอาจจะนานเกินไปในบางแพลตฟอร์ม ตัวอย่างเช่นบน Windows ขีด จำกัด พา ธ สำหรับ API เฟรมเวิร์กและแอปพลิเคชันบางตัวนั้นแย่มากซึ่งหมายความว่าคุณสามารถเข้าถึงขีด จำกัด ดังกล่าวได้อย่างง่ายดายหากไดเรกทอรีปัจจุบันลึกลงไปในลำดับชั้นของต้นไม้และชื่อไฟล์ชั่วคราวของคุณยาวเกินไป

  • บนเซิร์ฟเวอร์การตรวจสอบการเติบโตของไดเรกทอรีชั่วคราวมักจะทำทันที หากคุณใช้ไดเรกทอรีอื่นอาจไม่ได้รับการตรวจสอบและการตรวจสอบดิสก์ทั้งหมดจะไม่ช่วยให้เข้าใจได้ง่ายว่าเป็นไฟล์ชั่วคราวที่มีอยู่มากมาย

สำหรับข้อผิดพลาดที่ถูกปฏิเสธการเข้าถึงตรวจสอบให้แน่ใจว่าคุณให้ระบบปฏิบัติการสร้างไฟล์ชั่วคราวสำหรับคุณ ตัวอย่างเช่นระบบปฏิบัติการอาจทราบว่าสำหรับผู้ใช้ที่กำหนดไดเรกทอรีอื่นที่นอกเหนือจาก/tmpหรือC:\Windows\tempควรใช้ ดังนั้นโดยการเข้าถึงไดเรกทอรีเหล่านั้นโดยตรงคุณอาจพบข้อผิดพลาดถูกปฏิเสธการเข้าถึง

หากคุณได้รับการปฏิเสธการเข้าถึงแม้ว่าจะใช้การเรียกระบบปฏิบัติการก็หมายความว่าเครื่องได้รับการกำหนดค่าไม่ดี นี้ที่อธิบายแล้วโดย Blrfl ขึ้นอยู่กับผู้ดูแลระบบเพื่อกำหนดค่าเครื่อง คุณไม่ต้องเปลี่ยนใบสมัคร

การสร้างไฟล์ชั่วคราวนั้นตรงไปตรงมาในหลายภาษา ตัวอย่างบางส่วน:

  • ทุบตี:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
  • งูหลาม:

    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);
  • ทับทิม:

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

โปรดทราบว่าในบางกรณีเช่นใน PHP และ Ruby ไฟล์จะถูกลบออกเมื่อหมายเลขอ้างอิงถูกปิด นั่นคือประโยชน์เพิ่มเติมของการใช้ไลบรารีที่มาพร้อมกับภาษา / กรอบงาน


2
คุณหมายถึงอะไรโดย "ให้แน่ใจว่าคุณปล่อยให้ระบบปฏิบัติการสร้างไฟล์ชั่วคราวสำหรับคุณ" ดังนั้นแทนที่จะเป็นเช่นfopen("/tmp/mytmpfile", "w");ฉันควรทำการโทรของระบบเพื่อจัดการกับไฟล์ชั่วคราว?
simon

30
@gurka: คุณควรโทรหาtmpfile(3)เพื่อสร้างไฟล์ชั่วคราวหรืออย่างน้อยการโทรmktemp(3)เพื่อสร้างชื่อไฟล์
TMN

3
@TMN: พวกเขาเป็นเพียงฟังก์ชั่นห้องสมุดที่ทำงานในพื้นที่ผู้ใช้และพวกเขาไม่มีเวทมนตร์ใด ๆ ที่จะข้ามข้อผิดพลาดการอนุญาตที่กำหนดโดยระบบปฏิบัติการ
musiphil

25
@musiphil ทั้ง tmpfile และ mktemp ใช้ตัวแปรภายนอกเพื่อกำหนดพา ธ สำหรับไฟล์ชั่วคราว สิ่งเหล่านี้อาจถูกตั้งค่าให้ชี้ไปที่ไดเรกทอรีอื่นมากกว่า / tmp / อาจเป็นไดเรกทอรีต่อผู้ใช้ การพยายามสร้างชื่อไฟล์ด้วยตนเองใน / tmp / อาจล้มเหลวในขณะที่ tmpfile และ mktemp จะส่งคืนพา ธ ที่ถูกต้อง
ท่อ

2
@musiphil: ฉันไม่เคยบอกว่าพวกเขาต้องการแก้ไขปัญหาการอนุญาตฉันตอบคำถามของเขาเกี่ยวกับการใช้การเรียกของระบบเพื่อสร้างไฟล์
TMN

33

ฉันควรยืนยันว่าการบันทึกเป็น / tmp เป็นวิธีการที่ถูกต้องและป้องกันความล้มเหลวใด ๆ ว่า "ทำงานตามที่ตั้งใจ" (เช่นขอให้ผู้ดูแลระบบของคุณสำหรับการเข้าถึงการอนุญาตที่เหมาะสม)

มีมาตรฐานสำหรับสิ่งนี้และสิ่งที่ดีที่สุดที่คุณสามารถทำได้คือปฏิบัติตามพวกเขา

POSIX ซึ่งตามมาด้วยระบบปฏิบัติการที่ไม่ใช่เมนเฟรมทุกระบบที่มีความสำคัญใด ๆ ที่คุณอาจพบเจอมีข้อกำหนดสำหรับการสร้างไฟล์ชั่วคราวที่มีชื่อไม่ซ้ำกันในไดเรกทอรีโดยใช้ค่าเริ่มต้นที่สามารถกำหนดค่าได้ใหม่โดยสภาพแวดล้อม:

  • stdio.hส่วนหัวC อาจรวมถึงP_tmpdirแมโครที่ตั้งชื่อไดเรกทอรีชั่วคราวของระบบ
  • TMPDIRเป็นตัวแปรสภาวะแวดล้อมแบบบัญญัติสำหรับการเปลี่ยนตำแหน่งของไฟล์ชั่วคราว ก่อนที่จะ POSIX มีตัวแปรอื่น ๆ ที่ใช้ดังนั้นฉันมักจะไปกับครั้งแรกของนั้นหรือTMP, TEMPDIRและTEMPที่มีค่าเตะและการใช้ค่าเริ่มต้นระบบถ้าไม่มีผู้อยู่
  • mkstemp()และtempfile()ฟังก์ชั่นจะสร้างไฟล์ชั่วคราวที่ไม่ซ้ำกัน

หากผู้ใช้ของคุณถูกปฏิเสธความสามารถในการสร้างไฟล์ชั่วคราวระบบอาจถูกกำหนดค่าไว้ไม่ถูกต้องหรือผู้ดูแลระบบไม่ได้ระบุว่านโยบายของพวกเขานั้นเป็นอย่างไร ในกรณีดังกล่าวคุณจะมั่นใจในการบอกว่าโปรแกรมของคุณสอดคล้องกับมาตรฐานการพกพาที่ได้รับการยอมรับและพฤติกรรมสามารถเปลี่ยนแปลงได้โดยใช้ตัวแปรสภาพแวดล้อมที่มาตรฐานระบุไว้


P_tmpdirไม่ได้เป็นส่วนหนึ่งของstdio.hตามที่กำหนดโดยข้อกำหนดภาษา C มันอาจถูกกำหนดโดย POSIX หรือ SVID
musiphil

1
@musiphil: ตามที่ระบุไว้โดยคำตอบ (ชี้แจงตอนนี้) เป็นส่วนหนึ่งของ POSIX (ในทางเทคนิคก็เป็น / เปิดส่วนต่อขยายระบบ X ที่จัดตั้งขึ้น POSIX ดู. pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl

เห็นด้วยอย่างเต็มที่กับทุกข้อ ตัวอย่างที่ดีคือระบบ Linux ด้วยpam_tmpdir- ชุดนี้TMPDIRและTMPแตกต่างกันสำหรับผู้ใช้แต่ละคนเพื่อความทนทานและความเป็นส่วนตัว นอกจากนี้ยังมีประโยชน์ที่จะสามารถตั้งค่าTMPDIRสำหรับคำสั่งเดียว - ถ้าคุณมีไดเรกตอรีชั่วคราวตามปกติในระบบไฟล์ RAM สำหรับความเร็วคุณอาจต้องทำเช่นนี้สำหรับคำสั่งที่สร้างไฟล์ชั่วคราวขนาดใหญ่ (เช่นยักษ์sort) อย่าเพิกเฉยต่อมาตรฐาน / การประชุมที่ผู้ใช้คาดหวัง!
Toby Speight

ตรวจสอบสภาพแวดล้อมอย่างแน่นอนเพื่อหาตำแหน่งของไฟล์ชั่วคราวและอย่าใช้ hard-code / tmp เนื่องจาก tmp ที่ใช้ร่วมกันมีปัญหาด้านความปลอดภัยการบรรเทาหนึ่งที่ฉันเห็นบ่อยๆคือการสร้างไดเรกทอรีต่อผู้ใช้ / tmp โดยไม่ได้รับอนุญาตให้อ่านเขียนสำหรับผู้อื่น มันเอาสภาพการแข่งขันที่เป็นไปได้และการโจมตี symlink
Zan Lynx

9

temp-file-directory นั้นขึ้นอยู่กับระบบปฏิบัติการ / สภาพแวดล้อม ตัวอย่างเช่นเว็บเซิร์ฟเวอร์ - temp dir แยกจาก os-temp-dir ด้วยเหตุผลด้านความปลอดภัย

ภายใต้ ms-windows ผู้ใช้ทุกคนมี temp-dir ของตัวเอง

คุณควรใช้createTempFile ()สำหรับสิ่งนี้หากมีฟังก์ชั่นดังกล่าว


1
เพียงคำนึงถึงข้อ จำกัด ของระบบปฏิบัติการที่ซ่อนอยู่ใน Windows เราค้นพบวิธีที่ยากที่สุดที่จำนวนไฟล์สูงสุดในโฟลเดอร์ถูก จำกัด ไว้ที่ 65,565 แน่นอนว่านั่นเป็นจำนวนมากของไฟล์และตรวจสอบว่าคุณไม่ควรกลัวมีที่หลายวางรอบ แต่คุณแน่ใจหรือไม่ว่าทุกแอปทำความสะอาดตัวเองตามเวลาที่กำหนดและมีความประพฤติดี?
Mike Hofer

อ่าฉันเห็นความคิดเห็นของคุณช้าไปแล้ว ฉันเพิ่งเขียนเหมือนข้างบน BTW ข้อ จำกัด นั้นเกิดจากกลไกของฟังก์ชัน GetTimeFileName () ไม่ใช่ NTFS ว่าขีด จำกัด ของโฟลเดอร์ที่คุณกล่าวถึงใช้เฉพาะกับ FAT32
JensG

9

คำตอบก่อนหน้านี้ถึงแม้จะถูกต้อง แต่ก็ไม่ถูกต้องสำหรับกลุ่มคอมพิวเตอร์ขนาดใหญ่ส่วนใหญ่

กลุ่มคอมพิวเตอร์ไม่ปฏิบัติตามอนุสัญญามาตรฐานสำหรับเครื่องมักจะด้วยเหตุผลที่ดีและไม่มีประเด็นใดที่จะพูดคุยกับ sysadmins

ไดเรกทอรีปัจจุบันของคุณอ้างถึงระบบไฟล์ส่วนกลางซึ่งเข้าถึงได้ผ่านเครือข่าย สิ่งนี้ไม่เพียง แต่ช้า แต่ยังทำให้โหลดสำหรับผู้ใช้อื่น ๆ ด้วยดังนั้นคุณไม่ควรใช้มันจนกว่าคุณจะไม่ได้เขียนมากนักและคุณสามารถกู้คืนได้หากงานขัดข้อง

โหนดการคำนวณมีฮาร์ดไดรฟ์ของตัวเองซึ่งเป็นระบบไฟล์ที่เร็วที่สุดที่มีอยู่และสิ่งที่คุณควรใช้ เอกสารคลัสเตอร์ควรจะบอกคุณว่ามันคืออะไรโดยทั่วไป/scratch, /tmp/[jobid]หรือบางตัวแปรสภาพแวดล้อมที่ไม่ได้มาตรฐาน ( $SNIC_TMPหนึ่งในคนที่ผมใช้)

ดังนั้นสิ่งที่ฉันแนะนำคือทำให้ผู้ใช้สามารถกำหนดค่าได้ ค่าเริ่มต้นอาจเป็นค่าแรกที่คุณมีสิทธิ์เข้าถึงเพื่อเขียน:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

แต่คาดว่าจะมีอัตราความสำเร็จต่ำด้วยวิธีการนี้และให้แน่ใจว่าได้ปล่อยคำเตือนไขมันขนาดใหญ่

แก้ไข:ฉันจะเพิ่มเหตุผลอื่นเพื่อบังคับให้ตั้งค่าผู้ใช้ หนึ่งในกลุ่มของฉันได้$TMPDIRตั้งค่าไว้/scratchนั่นคือผู้ใช้เขียนได้และในฮาร์ดไดรฟ์ในเครื่อง แต่เอกสารระบุว่าสิ่งใดก็ตามที่คุณเขียนภายนอก/scratch/[jobid]อาจถูกลบได้ทุกเมื่อแม้แต่ในระหว่างการวิ่ง ดังนั้นถ้าคุณทำตามมาตรฐานและเชื่อใจ$TMPDIRคุณจะพบกับการล่มแบบสุ่มยากที่จะทำการดีบั๊ก ดังนั้นคุณอาจยอมรับ$TMPDIRแต่ไม่เชื่อใจมัน

กลุ่มอื่น ๆ มีการตั้งค่าตัวแปรนี้อย่างเหมาะสมดังนั้นคุณอาจเพิ่มตัวเลือกในการไว้วางใจอย่างชัดเจน$TMPDIRมิฉะนั้นปล่อยคำเตือนขนาดใหญ่และอ้วน


1
คำตอบก่อนหน้านี้ตรงไหนกัน
Tulains Córdova

2
ดังนั้นสิ่งที่คุณพูดในที่นี้คือเนื่องจากกลุ่มบางกลุ่มที่ไม่ใช้ขั้นตอนเล็กน้อยในการปฏิบัติตามมาตรฐานที่ได้รับการยอมรับอย่างดีสำหรับการบอกโปรแกรมว่าจะเขียนไฟล์ชั่วคราวไว้ที่ใดจึงเป็นหนึ่งในการปรับแต่งเพิ่มเติม ชาอ่อน ๆ ถ้าคุณถามฉัน
Blrfl

@ Blrfl คุณสามารถโบกมาตรฐานให้มากที่สุดเท่าที่คุณต้องการและเขียนโค้ดที่ปรับให้เข้ากับพวกมันได้อย่างสมบูรณ์แบบและขัดข้องเสมอ คุณสามารถลองต่อสู้กับ sysadmins ของแต่ละคลัสเตอร์ที่คุณใช้ หรือคุณสามารถยอมรับศรัทธาของคุณและทำให้มันกำหนดค่าได้ ยิ่งไปกว่านั้นใน HPC เรามักจะต้องปรับรหัสให้เหมาะกับคลัสเตอร์โดยเฉพาะ (RAM ที่มีอยู่, ความเร็วสัมพัทธ์ของระบบไฟล์, การใช้งาน MPI, ความพร้อมใช้งานทั่วไปของทรัพยากร ... ) ไม่มี "ขนาดเดียวที่เหมาะกับทุกคน"
Davidmh

@Davidmh: เข้าใจ แต่ไม่ใช่ประเด็น มาตรฐานทำให้สามารถกำหนดค่าได้ในลักษณะที่ไม่น่าอัศจรรย์ หากฉันนำรหัสที่เป็นที่รู้จักไปยังกลุ่มที่ไม่ได้ปฏิบัติตามมาตรฐานฉันจะต้องตั้งค่าไว้ในที่เดียวเช่นที่จุดเริ่มต้น นั่นคือสิ่งที่น้อยกว่าในรหัสที่เหลือเพื่อตรวจสอบแก้ไขและเสี่ยงต่อการผิด
Blrfl

1

สำหรับหลาย ๆ แอปพลิเคชั่นคุณควรพิจารณาใส่ไฟล์ชั่วคราวไว้ใน( $XDG_RUNTIME_DIRหรือไฟล์$XDG_CACHE_HOMEXDG อื่น ๆ ใช้สำหรับไฟล์แบบไม่ติดตั้งชั่วคราว) สำหรับคำแนะนำในการคำนวณพวกเขาหากพวกเขาไม่ได้ผ่านอย่างชัดเจนในสภาพแวดล้อมให้ดูข้อมูลจำเพาะ XDG basedirหรือหาห้องสมุดที่ดำเนินการแล้วส่วนนั้น

อย่างไรก็ตามโปรดทราบว่า$XDG_RUNTIME_DIRเป็นการเพิ่มใหม่และไม่มีทางเลือกมาตรฐานสำหรับระบบเก่าเนื่องจากความกังวลด้านความปลอดภัย

หากไม่เหมาะสมก็/tmpเป็นสถานที่ที่ถูกต้อง คุณไม่ควรถือว่าไดเรกทอรีปัจจุบันเขียนได้


-2

นี่เป็นอีกทางเลือกหนึ่ง แต่คุณอาจยกเลิกการเชื่อมโยง () ไฟล์ทันทีหลังจาก fopen () มันขึ้นอยู่กับรูปแบบการใช้งานของ cource

การยกเลิกการเชื่อมโยงไฟล์หากทำได้สามารถช่วยได้หลายวิธี:

  • ไม่เห็นไฟล์ - ผู้ใช้ไม่เห็น
  • ไม่เห็นไฟล์จากกระบวนการอื่น - ไม่มีโอกาสอื่นที่จะแก้ไขไฟล์โดยไม่ได้ตั้งใจ
  • ทำความสะอาดง่ายหากโปรแกรมขัดข้อง

ไฟล์จะต้องสร้างใน / tmp หากผู้ใช้ไม่มีสิทธิ์ในการสร้างไฟล์นั่นหมายความว่าระบบได้รับการกำหนดค่าผิดพลาด

ไม่สามารถสร้างไฟล์ในโฮมไดเรกทอรีของผู้ใช้ ผู้ใช้จำนวนมากเช่น "none", "www-data" และอื่น ๆ อีกมากมายไม่มีสิทธิ์เขียนในโฮมไดเร็กตอรี่ของพวกเขา, หรือแม้แต่ chroot () - ed. โปรดทราบว่าแม้ใน chroot environment / tmp ยังคงมีอยู่


แม้ว่านี่อาจเป็นความคิดที่ดี แต่ก็ไม่ได้ช่วยให้ผู้ใช้ที่ขาดสิทธิ์ในการเขียนในไดเรกทอรีสามารถสร้างไฟล์ได้
5gon12eder

4
นอกจากนี้ยังไม่ตอบคำถามซึ่งเป็นที่ที่จะวางไฟล์ชั่วคราว
Blrfl

ฉันเชื่อว่าคำตอบของฉันเป็นสิ่งสำคัญ ฉันแก้ไขแล้วอาจจะชัดเจนกว่านี้
นิค
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.