ความแตกต่างระหว่าง / tmp และ / run คืออะไร


42

ตามที่FHS-3.0 , /tmpเป็นไฟล์ชั่วคราวและ/runสำหรับข้อมูลตัวแปรเวลาทำงาน ข้อมูล/runจะต้องลบที่บูตต่อไปซึ่งไม่จำเป็นสำหรับการ/tmpแต่ยังคงโปรแกรมจะต้องไม่คิดว่าข้อมูลใน/tmpจะสามารถใช้ได้ในช่วงเริ่มต้นโปรแกรมถัดไป ทั้งหมดนี้ดูเหมือนจะค่อนข้างคล้ายกับฉัน

ดังนั้นความแตกต่างระหว่างสองคืออะไร เกณฑ์ใดที่โปรแกรมควรตัดสินใจว่าจะนำข้อมูลชั่วคราวไปไว้ใน/tmpหรือ/runไม่

ตามที่ FHS:

โปรแกรมอาจมีไดเรกทอรีย่อยของ/run; สิ่งนี้ได้รับการสนับสนุนสำหรับโปรแกรมที่ใช้มากกว่าหนึ่งไฟล์รันไทม์

สิ่งนี้บ่งชี้ว่าความแตกต่างระหว่าง "โปรแกรมระบบ" และ "โปรแกรมทั่วไป" ไม่ใช่เงื่อนไขและไม่ใช่อายุการใช้งานของโปรแกรม (เช่นกระบวนการที่ใช้เวลานานและระยะสั้น)

แม้ว่าจะไม่ได้ให้เหตุผลต่อไปนี้ใน FHS แต่/runก็ยังได้รับการแนะนำให้รู้จักกับปัญหาที่/varติดตั้งสายเกินไปดังนั้นจึงจำเป็นต้องมีลูกเล่นสกปรกเพื่อให้/var/runมีเร็วพอ แต่ตอนนี้มี/runการแนะนำและให้คำอธิบายใน FHS มีดูเหมือนจะไม่เป็นเหตุผลที่ชัดเจนที่จะมีทั้งและ/run/tmp


11
/ tmp เป็นตำแหน่งมาตรฐาน * nix สำหรับข้อมูลชั่วคราว / run เป็นตำแหน่งมาตรฐาน Poettering สำหรับข้อมูลชั่วคราว
ทำเครื่องหมาย

ความเข้ากันได้แบบย้อนหลังนั้นเป็นเหตุผลเสมอ ...
Bakuriu

คำตอบ:


16

ไม่มีเหตุผลที่จะมีทั้ง / run และ / tmp

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

เช่น daemon การพิมพ์ CUPS ไม่ได้ทำงานเหมือนรูท แต่โดยทั่วไปจะติดตั้งจากแพ็คเกจระบบปฏิบัติการ แพ็คเกจจะติดตั้ง/usr/lib/tmpfiles.d/cups.confและsystemd-tmpfilesสร้างไดเรกทอรีที่สามารถเข้าถึงได้ เนื่องจากไดเรกทอรีอยู่ภายใต้/runชื่อไม่สามารถถูกอ้างสิทธิ์โดยผู้ประสงค์ร้ายโดยไม่มีเจตนาได้/tmpซึ่งแตกต่างจากที่สามารถเขียนได้ทั่วโลก

"โปรแกรมที่ไม่ได้รับสิทธิพิเศษ" ซึ่งไม่สามารถใช้ได้/runโดยตรง

ความแตกต่างที่แท้จริงคือถ้าโปรแกรมของคุณกำลังถูกเรียกใช้โดยผู้ใช้ที่ไม่มีสิทธิพิเศษภายใต้ ID ผู้ใช้ของตนเอง แต่โดยทั่วไปคุณยังคงไม่ต้องการใช้/tmpเพราะสามารถเข้าถึงได้โดยผู้ใช้ที่ไม่มีสิทธิ์รายอื่น $XDG_RUNTIME_DIRคุณต้องการที่จะใช้ โดยทั่วไปจะมีการใช้งานเป็น/run/user/$(id -u)- ดังนั้นจึงเป็นไดเรกทอรีย่อยของ/runเช่นกัน แม้ว่าจะไม่รับประกันตำแหน่ง โปรแกรมควรใช้ตัวแปรสภาพแวดล้อมเสมอ

/tmpจะเป็นประโยชน์สำหรับความร่วมมือแบบเฉพาะกิจระหว่างผู้ใช้ที่ไม่มีสิทธิพิเศษต่างกันในระบบ ระบบ Ad-hoc ดังกล่าวมีความเสี่ยงต่อผู้ใช้ที่เป็นอันตรายที่ปฏิเสธที่จะร่วมมือและทำสิ่งต่าง ๆ ให้กับทุกคน :) ตัวอย่างหนึ่งคือผู้ใช้ที่ไม่มีสิทธิพิเศษที่ตัดสินใจใช้talkdaemon เวอร์ชันหนึ่งโดยใช้ซ็อกเก็ต unix

ข้อมูลต้นฉบับ จาก Lennart Poettering

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

การใช้เนมสเปซที่ใช้ร่วมกันที่เขียนได้ทั่วโลก [like / tmp] เพื่อจุดประสงค์ในการสื่อสารนั้นเป็นปัญหาเสมอมาเนื่องจากการสร้างการสื่อสารนั้นคุณต้องมีชื่อที่มั่นคง สิ่งนี้สามารถแก้ไขได้บางส่วนโดยสร้างไดเรกทอรีต่อแอพที่ได้รับการป้องกันสำหรับบริการบางอย่างระหว่างการบูทก่อนหน้า (เช่นที่เราทำสำหรับ X11) แต่สิ่งนี้จะแก้ไขปัญหาได้เพียงบางส่วนเท่านั้น

...

ฟีเจอร์ Fedora อีกตัว (สำหรับ Fedora 17) เปลี่ยนซีแมนทิกส์ของ / tmp สำหรับบริการระบบจำนวนมากเพื่อให้ปลอดภัยมากขึ้นโดยการแยก / tmp namespaces ของบริการต่างๆ

...

เนื่องจาก / tmp ไม่จำเป็นต้องเป็นเนมสเปซที่ใช้ร่วมกันอีกต่อไปจึงไม่เหมาะสมสำหรับสถานที่สำหรับการสื่อสารพื้นฐาน

...

[/ run] รับประกันว่าจะเป็น tmpfs และจะถูกล้างโดยอัตโนมัติที่บูท ไม่มีการทำความสะอาดอัตโนมัติเสร็จสิ้น

...

นี่คือคำแนะนำคร่าวๆเกี่ยวกับวิธีที่เราแนะนำให้คุณ (นักพัฒนาแอปพลิเคชัน Linux) เลือกไดเรกทอรีที่เหมาะสมในการใช้:

  1. คุณต้องมีที่วางซ็อกเก็ตของคุณ (หรือสื่อสารแบบดั้งเดิมอื่น ๆ ) และรหัสของคุณทำงานอภิสิทธิ์: ใช้ไดเรกทอรีย่อยใต้ / เรียกใช้ (หรือใต้ / var / run เพื่อความเข้ากันได้พิเศษ)
  2. คุณต้องมีที่วางซ็อกเก็ตของคุณ (หรือการสื่อสารดั้งเดิม) และโค้ดของคุณทำงานโดยไม่มีสิทธิพิเศษ: ใช้ไดเรกทอรีย่อยใต้ $ XDG_RUNTIME_DIR
  3. คุณต้องมีสถานที่ที่จะทำให้การดาวน์โหลดและการดาวน์โหลดที่มีขนาดใหญ่ขึ้นของคุณอยู่ในระหว่างดำเนินการและเรียกใช้แบบไม่มีสิทธิ์: ใช้ $ XDG_DOWNLOAD_DIR
  4. คุณต้องมีที่สำหรับวางแคชไฟล์ซึ่งควรจะคงอยู่และเรียกใช้ unprivileged: ใช้ $ XDG_CACHE_HOME
  5. ไม่มีสิ่งใดที่กล่าวมาข้างต้นและคุณจำเป็นต้องวางไฟล์ขนาดเล็กที่ไม่ต้องการความคงทน: ใช้ $ TMPDIR ด้วย fallback on / tmp และใช้ mkstemp () และ mkdtemp () และไม่มีอะไรพื้นบ้าน
  6. มิฉะนั้นให้ใช้ $ TMPDIR พร้อมกับทางเลือกใน / var / tmp ใช้ mkstemp () / mkdtemp () ด้วย

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

สิ่งหนึ่งที่เราต้องการเน้นคือ / tmp และ / var / tmp บ่อยกว่าไม่จริงไม่ใช่ตัวเลือกที่เหมาะสมสำหรับ usecase ของคุณ มีการใช้งานที่ถูกต้องของไดเรกทอรีเหล่านี้ แต่บ่อยครั้งที่ไดเรกทอรีอื่นอาจเป็นที่ที่ดีกว่า ดังนั้นระวังให้พิจารณาตัวเลือกอื่น ๆ แต่ถ้าคุณใช้สำหรับ / tmp หรือ / var / tmp อย่างน้อยต้องแน่ใจว่าใช้ mkstemp () / mkdtemp ()

พวกเราไปกับ/tmpซ็อกเก็ตดั้งเดิมที่ใช้โดยระบบ X window ดังที่อธิบายไว้ข้างต้นtmpfiles.d/x11.confผมอ่านผิด ดูเหมือนจะขึ้นอยู่กับความร่วมมือ :) ฉันถือว่ารหัสตรวจสอบแล้วการปฏิเสธการให้บริการนั้นเป็นสิ่งที่เลวร้ายที่สุดที่สามารถเกิดขึ้นได้


8
คำตอบนี้ผิดทุกชนิด
..

@R .. สนใจที่จะขยายที่?
Wildcard

ใช่ฉันตอบไปแล้ว (เริ่มต้นเป็นความคิดเห็น แต่ฉันรู้ว่ามันเป็นคำตอบที่มากขึ้น)
อา.

ฉันคิดว่าจุดอ่อนหลักในคำตอบปัจจุบันของฉันซึ่งฉันคิดว่าคุณกำลังทำอยู่คือในขณะที่ในทางเทคนิคการจัดการ XDG_RUNTIMEIME_DIR ที่ถูกต้องนั้นจำเป็นต้องพกพาไปยัง * nix ใด ๆ ("ถอยกลับไปยังไดเรกทอรีทดแทนที่มีความสามารถคล้ายกัน") มันคลุมเครือมากในสิ่งที่ความหมายนี้ในทางปฏิบัติ สำหรับโปรแกรมอรรถประโยชน์แบบพกพาควรใช้มาตรฐานที่กำหนดไว้อย่างดีสำหรับ/tmp("API เดียวสำหรับการใช้ควรเป็น mkstemp (), mkdtemp () (และเพื่อน ๆ ) เพื่อความปลอดภัยอย่างสมบูรณ์")
sourcejedi

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

23

ไดเรกทอรี/tmpและ/usr/tmp(ภายหลัง/var/tmp) เคยเป็นพื้นทิ้งสำหรับทุกอย่างและทุกคน กลไกการป้องกันเฉพาะสำหรับไฟล์ในไดเรกทอรีเหล่านี้เป็นบิตเหนียวซึ่ง จำกัด การลบหรือเปลี่ยนชื่อไฟล์ที่มีให้กับเจ้าของของพวกเขา ตามที่ marcelm ชี้ให้เห็นในความคิดเห็นไม่มีอะไรในหลักการที่ป้องกันไม่ให้ใครบางคนที่จะสร้างไฟล์ที่มีชื่อที่ใช้โดยบริการ (เช่นnginx.pidหรือsshd.pid) (ในทางปฏิบัติสคริปต์เริ่มต้นสามารถลบไฟล์ปลอมได้ก่อน)

/runก่อตั้งขึ้นสำหรับข้อมูลรันไทม์แบบไม่ถาวรของเซอร์วิสที่มีอายุใช้งานยาวนานเช่นล็อค, ซ็อกเก็ต, ไฟล์ pid และอื่น ๆ เนื่องจากไม่สามารถเขียนได้สำหรับสาธารณะจึงป้องกันข้อมูลรันไทม์ของบริการจากความยุ่งเหยิง/tmpและงานที่ทำความสะอาดอยู่ที่นั่น อันที่จริง: การแจกแจงสองครั้งที่ฉันเรียกใช้ (ไม่มีการเล่นสำนวนเจตนา) มีการอนุญาต 755 ใน/runขณะที่/tmpและ/var/tmp(และ/dev/shmสำหรับเรื่องนั้น) มีการอนุญาต 1777


3
มันเป็นเพียงมีข้อมูลรันไทม์บริการแยกต่างหากจากระเบียบใน/tmp - /tmpนอกจากนี้เพื่อให้เป็นท่าเรือที่ปลอดภัยสำหรับข้อมูลกล่าวว่าจากการทำความสะอาดงานต่างๆที่เหยียบย่ำไปทั่ว
Satō Katsura

ขอบคุณสำหรับข้อมูลเกี่ยวกับการอนุญาต อย่างไรก็ตามตาม FHS "โปรแกรมอาจมีไดเรกทอรีย่อยของ / run ซึ่งจะได้รับการสนับสนุนสำหรับโปรแกรมที่ใช้ไฟล์รันไทม์มากกว่าหนึ่งไฟล์" - สิ่งนี้ดูเหมือนจะขัดแย้งกับทั้งเกณฑ์ "อายุการใช้งานที่ยาวนาน" และการไม่สามารถของโปรแกรมในการสร้างไดเรกทอรีย่อยเนื่องจากสิทธิ์ที่ จำกัด
Dirk Herrmann

@DirkHerrmann ไม่ไม่ มีลักษณะที่/runและตรวจสอบที่ซับซ้อน (ดี ... ) โครงสร้างไดเรกทอรีที่เกิดจากudev, udiskฯลฯ ผมไม่ได้มีความเชี่ยวชาญในเรื่องนี้โดยเฉพาะอย่างยิ่ง แต่ฉันเดาสคริปต์บูต (ซึ่งจะทำงานเป็น superuser) ชุดทุกอย่างขึ้น
Countermode

2
"/ run ไม่จำเป็นต้องใช้ทางเทคนิคเพียงแค่แยกข้อมูลรันไทม์ของบริการออกจากระเบียบใน / tmp" - สิ่งที่ดีเช่นกันดังนั้นกระบวนการที่ไม่มีสิทธิพิเศษไม่สามารถใช้ชื่อบริการระบบที่ต้องการใช้ Kinda sucks ถ้า nginx ต้องการใช้/tmp/nginx.pidแต่มีอยู่แล้วเนื่องจากโปรแกรมทำงานผิดปกติบางอย่าง /run/ป้องกันสิ่งนี้โดยต้องการสิทธิ์ในการเขียน
marcelm

18

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

ในอดีตบางสิ่งบางอย่าง (เช่น X) ละเมิดหลักการนี้และใส่ชื่อที่รู้จักกันดี (ชอบ.X11-unix) /tmpใน หลักสูตรนี้เป็นบั๊กกี้และช่วยให้ผู้ใช้ DoS สามารถรับบริการที่ต้องการโดยการแข่งเพื่อสร้างไฟล์ด้วยชื่อที่ต้องการก่อน สิ่งต่าง ๆ เหล่านี้อยู่ภายใต้/run(หรือเทียบเท่า/var/runหากคุณไม่ได้สมัครเป็นสมาชิกการแก้ไขใหม่ Freedesktop.org) แน่นอนดียิ่งขึ้นคือการแก้ไขไม่ให้ใช้ชื่อที่รู้จักกันดีใน namespace ทั่วโลก แต่แทนที่จะผ่านรอบชื่อพา ธ


ขอบคุณสำหรับคำจำกัดความเพิ่มเติมเกี่ยวกับ "ไฟล์ชั่วคราว" แม้ว่าฉันจะไม่คิดว่า "ส่งผ่านชื่อพา ธ " อธิบายวิธีสร้างจุดประสานงาน โดยปกติแล้วคุณจะใช้ตัวแปรสภาพแวดล้อม ดูเหมือนว่ามีซ็อกเก็ตและท่อเพียงพอ (โดยทั่วไปใช้) เพื่อให้สามารถใช้งานได้ (ส่วนหนึ่งเป็นเพราะสิ่งต่าง ๆ มากมายจะทำงานผ่านซ็อกเก็ต dbus เดียวกัน) ดูเหมือนว่ามันจะสร้างความรำคาญให้กับการตั้งค่าสภาพแวดล้อมหากโปรแกรมไม่ได้เป็นค่าเริ่มต้นไปยังเส้นทางฮาร์ดโค้ด คุณสามารถเพิ่มคีย์ใหม่ให้กับ.socketไฟล์systemd ... แต่นั่นไม่ได้ช่วยให้ไดเรกทอรีทั้งหมดหรือสำหรับบริการที่ติดตั้งใหม่
sourcejedi

2
/run/FHS เองก็เป็นลูกบุญธรรมฉันไม่สามารถเห็นได้ว่ามีส่วนเกี่ยวข้องกับ fd.o อย่างไร นอกจากสิ่งที่เราตั้งใจจะบ่นจริงๆก็คือความพยายามในการพัฒนาที่ไม่ระบุรายละเอียด
sourcejedi

ฉันคิดว่าคำตอบเบื้องต้นที่นี่เป็นคำตอบที่ดีที่สุดสำหรับคำถามที่เขียน ฉันคิดว่ามันจะได้รับการปรับปรุงให้ดีขึ้นโดยพิจารณาจาก: _ เมื่อซอฟต์แวร์มีการเข้าถึงการเขียนไปยังไดเรกทอรีเฉพาะเช่นใต้/runอาจเลือกที่จะหลีกเลี่ยงความยุ่งเหยิงของ/tmpไดเรกทอรีที่ใช้ร่วมกันซึ่งมีไฟล์มากกว่านี้
sourcejedi

"fd.o" คืออะไร?
TRiG

7

ตามลำดับชั้นของระบบแฟ้ม

  • /run ใช้สำหรับข้อมูลตัวแปรรันไทม์เช่นข้อมูลเกี่ยวกับระบบที่ใช้งานตั้งแต่รีบูต
  • /tmp เป็นสถานที่ทั่วไปสำหรับไฟล์ชั่วคราว

ดังนั้นสิ่งที่เกี่ยวกับสถานภาพภูตผู้ใช้ล็อกอินติดตั้งอุปกรณ์ที่ถอดออก ฯลฯ จะไปในขณะที่ไฟล์ชั่วคราวที่สร้างขึ้นโดยโปรแกรมจะไปเป็น/run/tmp

แก้ไข: ตามที่ระบุโดย @JdeBP ในความคิดเห็นด้านล่าง

FHS ช่วยให้สิ่งต่าง ๆ เช่นการติดตั้งแบบธรรมดาของงาน cron ที่กำจัด/tmpไฟล์ "เก่า" เป็นประจำ /runไม่มีกลไกดังกล่าวมีไว้สำหรับ ดังนั้นขีด จำกัด /tmpเข้มงวดเกี่ยวกับสิ่งที่โปรแกรมสามารถคาดหวังของชีวิตอะไรใส่ใน ในขณะที่โปรแกรมสามารถคาดหวังว่าไฟล์จะมีชีวิตอยู่ได้นานขึ้นใน/runระบบที่ต่อเนื่อง แต่พวกเขาก็คาดว่าจะมีระเบียบมากขึ้น


4
มีสิ่งหนึ่งที่ไม่ได้ชี้ให้เห็นในคำตอบนี้หรือคำตอบอื่น ๆ แต่มีการระบุไว้ใน FHS และคุณอาจต้องการปรับปรุงคำตอบของคุณด้วย: FHS ช่วยให้สิ่งต่าง ๆ เช่นการติดตั้งแบบธรรมดาของงาน cron ที่กำจัด/tmpไฟล์เก่า ๆ /runไม่มีกลไกดังกล่าวมีไว้สำหรับ ดังนั้นขีด จำกัด /tmpเข้มงวดเกี่ยวกับสิ่งที่โปรแกรมสามารถคาดหวังของชีวิตอะไรใส่ใน ในขณะที่โปรแกรมสามารถคาดหวังว่าไฟล์จะมีชีวิตอยู่ได้นานขึ้นใน/runระบบที่ต่อเนื่อง แต่พวกเขาก็คาดว่าจะมีระเบียบมากขึ้น
JdeBP

1
มันจะเป็นการดีถ้ามีไดเรกทอรีต่อกระบวนการของสิ่งต่าง ๆ ที่หายไป (หรือได้รับอนุญาตให้ถูกลบโดยดีมอนขยะบางตัว) ในทันทีที่กระบวนการตาย
Omnifarious

1
@Omnifarious ตอนนี้คุณสามารถรับพฤติกรรมนั้นสำหรับบริการ systemd โดยใช้RuntimeDirectory = :-)
sourcejedi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.